using System;
using System.Collections.Generic;
using System.Security;
using System.Threading;
using System.Transactions;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.MTS;
using OracleInternal.Network;
using OracleInternal.ServiceObjects;
using OracleInternal.Sharding;

namespace OracleInternal.ConnectionPool
{
	internal abstract class PoolManager<PM, CP, PR> where PM : PoolManager<PM, CP, PR>, new()where CP : Pool<PM, CP, PR>, new()where PR : PoolResource<PM, CP, PR>, new()
	{
		internal enum CriteriaNames
		{
			ConnectionClass,
			Edition,
			TagName
		}

		internal enum CriteriaTypes
		{
			MustMatchCriteria,
			AlterableSessionCriteria,
			TagCriteria
		}

		public ConnectionPoolId m_conPoolKey;

		public SyncDictionary<string, SyncDictionary<string, CP>> m_dictDictCP;

		public SyncDictionary<string, SyncDictionary<string, TransactionContext<PM, CP, PR>>> m_dictDictTxnCtx;

		public SyncQueueList<CP> m_pmListCP;

		public SyncQueueList<PR> m_pmListPR;

		public SyncQueueList<CP> m_pmDeactivatedCP;

		public SyncQueueList<TransactionContext<PM, CP, PR>> m_pmListTxnCtx;

		public SyncDictionary<string, ServiceCtx> m_dictSvcCtx;

		private static ReaderWriterLockSlim m_serviceDomainDictLocker;

		private static SyncDictionary<string, string> m_serviceDSDict;

		private static SyncDictionary<string, string> m_domainDSDict;

		internal SyncDictionary<string, string> m_defaultEditionDict = new SyncDictionary<string, string>();

		internal object m_syncObjForDefaultSvcRelocWait = new object();

		public ConnectionString m_cs;

		internal bool m_bHAEnabled;

		internal bool m_bUsingSEPSCredentials;

		internal bool m_bSEPSForProxyCredentials;

		internal bool m_bSEPSCredentialsFetched;

		internal bool? m_bReadOnlyChunkOK;

		internal OracleCredential m_orclCredential;

		public SecureString m_securedPassword;

		public SecureString m_securedProxyPassword;

		private object m_creationSync;

		private object m_syncPRClose;

		private object m_txnAffinityLock;

		private object m_syncTxnCtx;

		internal Timer m_timer;

		internal bool m_bDefaultsFetched;

		internal string m_databaseDomainName;

		internal string m_databaseName;

		internal string m_conStrServiceName;

		internal string m_conStrPdbName;

		public int m_drain_timeout;

		internal object m_conStrDefaultsLocker = new object();

		internal object m_defaultEditionLocker = new object();

		public Semaphore m_semIdleResource;

		public Semaphore m_semMaxPoolSize;

		public Semaphore m_semIncrPoolSize;

		public WaitHandle[] m_IdleAndIncrHandles;

		public WaitHandle[] m_IdleAndMaxHandles;

		public Semaphore m_semPoolPopulation;

		public string m_serverVersion;

		public string m_fullDescriptor;

		internal ConnectionOption m_connOpt;

		public string m_tnsAdmin;

		internal string m_walletLocation;

		public bool m_bKeepAlive;

		public int m_keepAliveTime;

		public int m_keepAliveInterval;

		public CP m_pmSingleCP;

		public TimeSpan m_timeoutValue;

		public string m_id;

		private int m_maxPoolSize;

		internal bool m_bSelfTuningDisabled;

		public int m_rlbMissCount;

		private const int MAX_RLB_MISS_COUNT = 2000;

		private int m_currentMaxSemCount;

		private int m_currentIncrSemCount;

		private int m_currentIdleSemCount;

		internal bool m_bResolveTnsAlias = true;

		internal bool? m_bNAEInUse;

		private IntPtr pShardCtx = IntPtr.Zero;

		internal CriteriaMapper m_criteriaMapper;

		internal Dictionary<string, ClientInitiatedConnection> m_CQNListeners = new Dictionary<string, ClientInitiatedConnection>();

		internal object m_syncCQNObject = new object();

		internal short MAX_CQN_LISTENERS_PER_POOL = 1;

		internal int MAX_REG_PER_CQN_LISTENER = int.MaxValue;

		internal static string[] m_criteriaArray;

		internal static int[] m_criteriaToCritTypeArray;

		internal static int[] m_criteriaToCritTypeForDTXN;

		internal object m_lockDeadConnectionScan;

		internal object m_lockUnPopulatePool;

		internal object m_lockGetSync;

		protected ShardRoutingCache m_shardRoutingCache;

		protected static SyncDictionary<string, SyncDictionary<string, ShardRoutingCache>> m_shardRoutingCacheDict;

		internal string m_chunkMigrationConTimeout;

		internal string m_drcpConnectionClass;

		public ConnectionString ConnectionString => m_cs;

		static PoolManager()
		{
			m_serviceDomainDictLocker = new ReaderWriterLockSlim();
			m_serviceDSDict = new SyncDictionary<string, string>();
			m_domainDSDict = new SyncDictionary<string, string>();
			m_shardRoutingCacheDict = new SyncDictionary<string, SyncDictionary<string, ShardRoutingCache>>();
			m_criteriaToCritTypeArray = new int[2];
			m_criteriaToCritTypeArray[0] = 0;
			m_criteriaToCritTypeArray[1] = 1;
			m_criteriaToCritTypeForDTXN = new int[2];
			m_criteriaToCritTypeForDTXN[0] = 0;
			m_criteriaToCritTypeForDTXN[1] = 0;
			m_criteriaArray = new string[2];
			m_criteriaArray[0] = "ConnectionClass";
			m_criteriaArray[1] = "Edition";
		}

		public PoolManager()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.ctor);
			}
			try
			{
				m_dictDictCP = new SyncDictionary<string, SyncDictionary<string, CP>>();
				m_pmListCP = new SyncQueueList<CP>();
				m_pmListPR = new SyncQueueList<PR>();
				m_pmListTxnCtx = new SyncQueueList<TransactionContext<PM, CP, PR>>();
				m_dictDictTxnCtx = new SyncDictionary<string, SyncDictionary<string, TransactionContext<PM, CP, PR>>>();
				m_dictSvcCtx = new SyncDictionary<string, ServiceCtx>();
				m_creationSync = new object();
				m_syncPRClose = new object();
				m_txnAffinityLock = new object();
				m_syncTxnCtx = new object();
				m_orclCredential = null;
				m_id = GetHashCode().ToString();
				m_criteriaMapper = new CriteriaMapper();
				m_lockDeadConnectionScan = new object();
				m_lockUnPopulatePool = new object();
				m_lockGetSync = new object();
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.ctor, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.ctor);
				}
			}
		}

		internal string GetCQNListenerClientId()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetCQNListenerClientId);
			}
			string text = null;
			try
			{
				lock (m_syncCQNObject)
				{
					if (m_CQNListeners != null)
					{
						foreach (KeyValuePair<string, ClientInitiatedConnection> cQNListener in m_CQNListeners)
						{
							if (cQNListener.Value.m_cqnRegistrations.Count < MAX_REG_PER_CQN_LISTENER)
							{
								text = cQNListener.Key;
								break;
							}
						}
						if (string.IsNullOrEmpty(text) && m_CQNListeners.Count >= MAX_CQN_LISTENERS_PER_POOL)
						{
							int num = int.MaxValue;
							foreach (KeyValuePair<string, ClientInitiatedConnection> cQNListener2 in m_CQNListeners)
							{
								if (cQNListener2.Value.m_cqnRegistrations.Count < num)
								{
									num = cQNListener2.Value.m_cqnRegistrations.Count;
									text = cQNListener2.Key;
								}
							}
						}
					}
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetCQNListenerClientId, $"Returning listenerClientId: {text}");
				}
				return text;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetCQNListenerClientId);
				}
			}
		}

		internal void AddCQNRestration(string listenerClientId, int registrationId, ClientInitiatedConnection clientConn)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.AddCQNRestration);
			}
			try
			{
				lock (m_syncCQNObject)
				{
					if (clientConn == null)
					{
						if (!string.IsNullOrEmpty(listenerClientId))
						{
							if (m_CQNListeners.ContainsKey(listenerClientId))
							{
								ClientInitiatedConnection clientInitiatedConnection = m_CQNListeners[listenerClientId];
								clientInitiatedConnection.m_cqnRegistrations.Add(registrationId);
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.PoolManager, OracleTraceFuncName.AddCQNRestration, $"Added registration {registrationId} against CIC:{listenerClientId}, Total Registration={clientInitiatedConnection.m_cqnRegistrations.Count}, Total Listeners={m_CQNListeners.Count}");
								}
							}
							else if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.AddCQNRestration, $"UNEXPECTD => listenerClientId: {listenerClientId} not found in list of m_CQNListeners with count: {m_CQNListeners.Count}");
							}
						}
						else if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.AddCQNRestration, $"UNEXPECTD => listenerClientId is NullOrEmpty");
						}
					}
					else
					{
						clientConn.m_cqnRegistrations.Add(registrationId);
						m_CQNListeners.Add(listenerClientId, clientConn);
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.PoolManager, OracleTraceFuncName.AddCQNRestration, $"Added registration {registrationId} against new CIC:{listenerClientId}, Total Registration={clientConn.m_cqnRegistrations.Count}, Total Listeners={m_CQNListeners.Count}");
						}
					}
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.AddCQNRestration);
				}
			}
		}

		internal void RemoveCQNRestration(string listenerClientId, int registrationId)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCQNRestration);
			}
			try
			{
				lock (m_syncCQNObject)
				{
					if (!string.IsNullOrEmpty(listenerClientId))
					{
						if (m_CQNListeners.ContainsKey(listenerClientId))
						{
							ClientInitiatedConnection clientInitiatedConnection = m_CQNListeners[listenerClientId];
							for (int i = 0; i < clientInitiatedConnection.m_cqnRegistrations.Count; i++)
							{
								if (registrationId == clientInitiatedConnection.m_cqnRegistrations[i])
								{
									clientInitiatedConnection.m_cqnRegistrations.RemoveAt(i);
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCQNRestration, $"Removed registration {registrationId} against new CIC:{listenerClientId}, Total Registration={clientInitiatedConnection.m_cqnRegistrations.Count}, Total Listeners={m_CQNListeners.Count}");
									}
									break;
								}
							}
							if (clientInitiatedConnection.m_cqnRegistrations.Count == 0)
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCQNRestration, $"No more registrations remaining against CIC:{listenerClientId}, Initiate SHUTDOWN of this CIC");
								}
								m_CQNListeners[listenerClientId].ShutDownListener();
								m_CQNListeners.Remove(listenerClientId);
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCQNRestration, $"Remaining CIC Listener Count:{m_CQNListeners.Count}");
								}
							}
						}
						else if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCQNRestration, $"UNEXPECTD => listenerClientId: {listenerClientId} not found in list of m_CQNListeners with Count: {m_CQNListeners.Count}");
						}
					}
					else if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCQNRestration, $"UNEXPECTD => listenerClientId is NullOrEmpty");
					}
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCQNRestration);
				}
			}
		}

		internal virtual void ResolveTnsAlias(ConnectionString cs, object OC = null)
		{
			if (string.IsNullOrEmpty(cs.m_dataSource) || !m_cs.m_pooling)
			{
				return;
			}
			lock (OracleConnectionDispenser<OraclePoolManager, OraclePool, OracleConnectionImpl>.m_syncObjForGetDataSources)
			{
				if (OracleConnectionDispenser<PM, CP, PR>.m_listDataSources != null)
				{
					OracleConnectionDispenser<PM, CP, PR>.m_listDataSources.Add(cs.m_dataSource);
				}
				string text = ((OracleCommunication)OC).Resolve(cs.m_dataSource, out m_connOpt);
				if (text != null && text.TrimStart(HelperClass.WHITE_SPACE_DELIMS).StartsWith("("))
				{
					m_fullDescriptor = text;
				}
			}
		}

		internal virtual void Initialize(ConnectionString cs, OracleConnection con)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Initialize, "(constr=" + cs.m_conPoolKey.m_pwdLessconnString + ")");
			}
			try
			{
				m_cs = cs;
				m_conPoolKey = cs.m_conPoolKey;
				m_semPoolPopulation = new Semaphore(1, 1);
				m_IdleAndIncrHandles = new WaitHandle[2];
				m_semIdleResource = new Semaphore(0, m_cs.m_maxPoolSize);
				m_IdleAndIncrHandles[0] = m_semIdleResource;
				m_semIncrPoolSize = new Semaphore(m_cs.m_incrPoolSize, m_cs.m_incrPoolSize);
				m_IdleAndIncrHandles[1] = m_semIncrPoolSize;
				m_semMaxPoolSize = new Semaphore(m_cs.m_maxPoolSize, m_cs.m_maxPoolSize);
				m_maxPoolSize = m_cs.m_maxPoolSize;
				m_IdleAndMaxHandles = new WaitHandle[2];
				m_IdleAndMaxHandles[0] = m_semIdleResource;
				m_IdleAndMaxHandles[1] = m_semMaxPoolSize;
				m_drcpConnectionClass = null;
				if (con != null && !string.IsNullOrEmpty(con.DRCPConnectionClass))
				{
					m_drcpConnectionClass = con.DRCPConnectionClass;
				}
				if (m_cs.m_poolRegulator > 0)
				{
					m_timer = new Timer(new TimerCallback(RLBGravitateThreadFunc), new object[3]
					{
						m_cs.m_decrPoolSize,
						null,
						m_drcpConnectionClass
					}, m_cs.m_poolRegulator * 1000, m_cs.m_poolRegulator * 1000);
				}
				if (m_cs.m_connectionTimeout > 2147483)
				{
					m_timeoutValue = TimeSpan.FromSeconds(2147483.0);
				}
				else
				{
					m_timeoutValue = TimeSpan.FromSeconds(m_cs.m_connectionTimeout);
				}
				m_pmListTxnCtx.m_max = cs.m_maxPoolSize;
				m_pmListTxnCtx.m_bMaxExplicitlySet = true;
				m_currentMaxSemCount = m_cs.m_maxPoolSize;
				m_currentIdleSemCount = m_cs.m_incrPoolSize;
				int num = (cs.m_haEvents ? 1 : 0);
				if (!cs.m_haEventsPresentInConnString)
				{
					num = Convert.ToInt32(ConfigBaseClass.m_haEvents);
				}
				m_bHAEnabled = ((num == 1) ? true : false);
				if (con != null)
				{
					m_tnsAdmin = con.TnsAdminInternal;
					m_walletLocation = con.WalletLocationInternal;
					m_bKeepAlive = con.KeepAlive;
					m_keepAliveTime = con.KeepAliveTime;
					m_keepAliveInterval = con.KeepAliveInterval;
					m_chunkMigrationConTimeout = con.m_chunkMigrationConTimeout;
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.Initialize, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.Initialize, "(pmid=" + m_id + ") (constr=" + cs.m_conPoolKey.m_pwdLessconnString + ")");
				}
			}
		}

		internal virtual void InitializeSelfTuning()
		{
		}

		public int GetNumberOfIdleConnections()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetNumberOfIdleConnections);
			}
			try
			{
				int num = 0;
				List<CP> list = m_pmListCP.GetList();
				for (int i = 0; i < list.Count; i++)
				{
					num += list[i].m_cpQueuePR.Count;
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetNumberOfIdleConnections, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetNumberOfIdleConnections);
				}
			}
		}

		public void UnPopulatePoolThreadFunc(object state)
		{
			UnPopulatePool(state);
		}

		public int UnPopulatePool(object state)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.UnPopulatePool);
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			string text = string.Empty;
			string empty = string.Empty;
			if (Monitor.TryEnter(m_lockUnPopulatePool))
			{
				try
				{
					UnPopulatePoolArgs unPopulatePoolArgs = (UnPopulatePoolArgs)state;
					num4 = unPopulatePoolArgs.m_decrementCount;
					text = ((unPopulatePoolArgs.m_instanceName == null) ? null : unPopulatePoolArgs.m_instanceName.ToLowerInvariant());
					empty = ((unPopulatePoolArgs.m_serviceName == null) ? null : unPopulatePoolArgs.m_serviceName.ToLowerInvariant());
					bool flag = num4 == -1;
					List<PR> list = ((text == null || empty == null) ? m_pmListPR.GetList() : m_dictDictCP[empty][text].m_cpListPR.GetList());
					if (m_pmListCP.Count == 1)
					{
						num3 = Math.Min(num4, m_pmListCP[0].m_cpQueuePR.Count);
					}
					else
					{
						num2 = GetNumberOfIdleConnections();
						num3 = Math.Max(0, Math.Min(num4, num2 - m_cs.m_minPoolSize));
					}
					for (int i = 0; i < list.Count; i++)
					{
						if (!flag && num >= num3)
						{
							break;
						}
						try
						{
							bool flag2 = false;
							PR val = list[i];
							if ((text == null || empty == null || (empty != null && val.ServiceName.ToLowerInvariant() == empty && text != null && val.m_instanceName.ToLowerInvariant() == text)) && !val.m_bCheckedOutByApp && !val.m_bCheckedOutByDTC && val.m_bPutCompleted && (val.m_mtsTxnCtx == null || (val.m_mtsTxnCtx != null && val.m_mtsTxnCtx.m_txnType == MTSTxnType.None)))
							{
								lock (val)
								{
									if (!val.m_bCheckedOutByApp && !val.m_bCheckedOutByDTC && val.m_bPutCompleted && (val.m_mtsTxnCtx == null || (val.m_mtsTxnCtx != null && val.m_mtsTxnCtx.m_txnType == MTSTxnType.None)))
									{
										if (!flag)
										{
											flag2 = true;
											if (val.m_deletionRequestor != DeletionRequestor.HA)
											{
												val.m_deletionRequestor = DeletionRequestor.PoolRegulator;
											}
										}
										else
										{
											if (val.m_deletionRequestor == DeletionRequestor.HA)
											{
												flag2 = true;
											}
											if (!flag2)
											{
												flag2 = !val.TransportAlive();
												if (flag2)
												{
													if (ProviderConfig.m_bTraceLevelPrivate)
													{
														string str = $"({val.m_endUserSessionId}:{val.m_endUserSerialNum})";
														Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.UnPopulatePool, str + " : (HA) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
													}
													val.m_deletionRequestor = DeletionRequestor.HA;
												}
											}
										}
										if (flag2)
										{
											if (val.m_pm.Close(val, null))
											{
												num++;
											}
											else if (!flag && val.m_deletionRequestor != DeletionRequestor.HA)
											{
												val.m_deletionRequestor = DeletionRequestor.None;
											}
										}
									}
								}
							}
							if (val != null && !flag2 && flag)
							{
								val.m_bReconnectAtNullState = true;
							}
						}
						catch (Exception ex)
						{
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.UnPopulatePool, ex.ToString());
							}
						}
						finally
						{
							if (num >= num3)
							{
								flag = true;
							}
						}
					}
				}
				catch (Exception ex2)
				{
					OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.UnPopulatePool, ex2);
				}
				finally
				{
					Monitor.Exit(m_lockUnPopulatePool);
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.UnPopulatePool, "(RLB) UnPopulatePool(instance=" + text + "; request to close=" + num4 + "; attempt to close=" + num3 + "; idle=" + num2 + "; min=" + m_cs.m_minPoolSize + "; closed=" + num + ")");
					}
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.UnPopulatePool);
					}
				}
			}
			return num;
		}

		public void PopulatePoolThreadFunc(object state)
		{
			PopulatePool(state);
		}

		public int PopulatePool(object state)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.PopulatePool, "(count=" + ((PoolPopulationOption)state).m_requestCount + ")(target=" + ((PoolPopulationOption)state).m_targetCount + ")");
			}
			int num = 0;
			PoolPopulationOption poolPopulationOption = (PoolPopulationOption)state;
			OracleConnection oracleConnection = null;
			if (poolPopulationOption.m_connectionClass != null)
			{
				oracleConnection = new OracleConnection();
				oracleConnection.m_criteriaConnCls = poolPopulationOption.m_connectionClass;
			}
			try
			{
				try
				{
					for (int i = 0; i < poolPopulationOption.m_requestCount; i++)
					{
						bool flag = false;
						bool flag2 = false;
						if (m_pmListPR.Count >= poolPopulationOption.m_targetCount)
						{
							return num;
						}
						flag = m_semMaxPoolSize.WaitOne(0);
						if (!flag)
						{
							return num;
						}
						PR val = null;
						try
						{
							if (poolPopulationOption.m_ignoreIncrPoolSize)
							{
								val = CreateNewPR(1, bForPoolPopulation: true, null, oracleConnection);
								continue;
							}
							flag2 = m_semIncrPoolSize.WaitOne(0);
							if (flag2)
							{
								val = CreateNewPR(1, bForPoolPopulation: true, null, oracleConnection);
							}
						}
						catch
						{
							goto IL_028b;
						}
						finally
						{
							if (flag2)
							{
								try
								{
									m_currentIncrSemCount = m_semIncrPoolSize.Release();
								}
								catch
								{
									throw new Exception("m_semIncrPoolSize.Release2() threw exception with count = " + m_currentIncrSemCount);
								}
								flag2 = false;
							}
							if (val != null)
							{
								num++;
							}
							else if (flag)
							{
								m_currentMaxSemCount = m_semMaxPoolSize.Release();
								flag = false;
							}
						}
					}
				}
				catch (Exception ex)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.PopulatePool, ex.ToString());
					}
				}
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.PopulatePool, ex2);
			}
			finally
			{
				if (poolPopulationOption.m_semPoolPopulation != null)
				{
					poolPopulationOption.m_semPoolPopulation.Release();
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.PopulatePool, "PopulatePoolThreadFunc(created=" + num + "; max=" + m_cs.m_maxPoolSize + "; total=" + m_pmListPR.Count + ")");
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.PopulatePool);
				}
			}
			goto IL_028b;
			IL_028b:
			return num;
		}

		public virtual void PutCP(PR pr, CP cp)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.PutCP);
			}
			try
			{
				cp.m_pm = (PM)this;
				if (cp.m_instanceName == null || cp.m_serviceName == null)
				{
					cp.m_instanceName = pr.m_instanceName;
					cp.m_serviceName = pr.ServiceName;
				}
				m_dictDictCP[pr.ServiceName.ToLowerInvariant()][pr.m_instanceName.ToLowerInvariant()] = cp;
				lock (m_creationSync)
				{
					m_pmListCP.Add(cp);
				}
				if (OraclePool.m_bPerfNumberOfInactiveConnectionPools)
				{
					OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfInactiveConnectionPools, pr as OracleConnectionImpl, cp as OraclePool);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.PutCP, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.PutCP, "(total={0})", m_pmListCP.Count.ToString());
				}
			}
		}

		public virtual void PutNewPR(PR pr, bool bForPoolPopulation)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.PutNewPR, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			try
			{
				lock (pr)
				{
					if (bForPoolPopulation)
					{
						pr.m_bPutCompleted = true;
					}
					else
					{
						pr.m_bPutCompleted = false;
					}
				}
				m_pmListPR.Add(pr);
				pr.m_pm = (PM)this;
				_ = pr.ServiceName;
				CreateServiceCtx(pr);
				if (m_cs.m_pooling)
				{
					bool migratePR = false;
					AddPRToPool(pr, bForPoolPopulation, migratePR);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.PutNewPR, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.PutNewPR, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
				}
			}
		}

		public void SetServiceForDS(string dataSource, string serviceName)
		{
			if (m_serviceDSDict.ContainsKey(dataSource))
			{
				return;
			}
			try
			{
				m_serviceDomainDictLocker.EnterWriteLock();
				if (!m_serviceDSDict.ContainsKey(dataSource))
				{
					m_serviceDSDict[dataSource] = serviceName;
				}
			}
			finally
			{
				m_serviceDomainDictLocker.ExitWriteLock();
			}
		}

		public string GetServiceForDS(string dataSource)
		{
			string result = null;
			try
			{
				m_serviceDomainDictLocker.EnterReadLock();
				if (m_serviceDSDict.ContainsKey(dataSource))
				{
					return m_serviceDSDict[dataSource];
				}
				return result;
			}
			finally
			{
				m_serviceDomainDictLocker.ExitReadLock();
			}
		}

		public void SetDomainForDS(string dataSource, string domainName)
		{
			if (m_domainDSDict.ContainsKey(dataSource))
			{
				return;
			}
			try
			{
				m_serviceDomainDictLocker.EnterWriteLock();
				if (!m_domainDSDict.ContainsKey(dataSource))
				{
					m_domainDSDict[dataSource] = domainName;
				}
			}
			finally
			{
				m_serviceDomainDictLocker.ExitWriteLock();
			}
		}

		public string GetDomainForDS(string dataSource)
		{
			string result = null;
			try
			{
				m_serviceDomainDictLocker.EnterReadLock();
				if (m_domainDSDict.ContainsKey(dataSource))
				{
					return m_domainDSDict[dataSource];
				}
				return result;
			}
			finally
			{
				m_serviceDomainDictLocker.ExitReadLock();
			}
		}

		private void AddPRToPool(PR pr, bool bForPoolPopulation, bool migratePR)
		{
			string key = pr.ServiceName.ToLowerInvariant();
			if (migratePR && pr.m_cp != null)
			{
				pr.m_cp.m_cpListPR.Remove(pr);
			}
			if (m_dictDictCP[key] == null)
			{
				lock (m_dictDictCP)
				{
					if (m_dictDictCP[key] == null)
					{
						m_dictDictCP[key] = new SyncDictionary<string, CP>();
					}
				}
			}
			if (!m_dictDictCP[key].ContainsKey(pr.m_instanceName.ToLowerInvariant()))
			{
				lock (m_dictDictCP)
				{
					if (!m_dictDictCP[key].ContainsKey(pr.m_instanceName.ToLowerInvariant()))
					{
						CP val = new CP();
						PutCP(pr, val);
						val.PutNewPR(pr, bForPoolPopulation);
						m_dictSvcCtx[key].m_roundRobin.SetMax(m_dictDictCP[key].Count);
					}
					else
					{
						pr.m_cp = m_dictDictCP[key][pr.m_instanceName.ToLowerInvariant()];
						pr.m_cp.PutNewPR(pr, bForPoolPopulation);
					}
				}
			}
			else
			{
				pr.m_cp = m_dictDictCP[key][pr.m_instanceName.ToLowerInvariant()];
				pr.m_cp.PutNewPR(pr, bForPoolPopulation);
			}
			if (bForPoolPopulation)
			{
				m_currentIdleSemCount = m_semIdleResource.Release();
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.AddPRToPool, $"PM.PutNewPR() : Idle Sempahore count={m_currentIdleSemCount}");
			}
		}

		private void CreateServiceCtx(PR pr)
		{
			string text = pr.ServiceName.ToLowerInvariant();
			if (m_dictSvcCtx.ContainsKey(text))
			{
				return;
			}
			lock (m_dictSvcCtx)
			{
				if (!m_dictSvcCtx.ContainsKey(text))
				{
					m_dictSvcCtx[text] = new ServiceCtx(text);
					m_dictSvcCtx[text].m_databaseName = pr.m_databaseName;
				}
			}
		}

		public void CreateNewPRThreadFunc(object state)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPRThreadFunc);
			}
			try
			{
				object[] obj = state as object[];
				PR val = (PR)obj[0];
				OracleConnection connRefForCriteria = (OracleConnection)obj[1];
				if (val != null && ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPRThreadFunc, "(initiated by TID:" + val.requestingThreadId + ")");
				}
				ManualResetEventSlim eventConCreated = val.m_eventConCreated;
				ManualResetEventSlim eventConTimeout = val.m_eventConTimeout;
				try
				{
					if (val.m_cs == null)
					{
						val.Connect(m_cs, bForPoolPopulation: true, connRefForCriteria, val.m_affinityInstance);
					}
					else
					{
						val.Connect(val.m_cs, bForPoolPopulation: true, connRefForCriteria, val.m_affinityInstance);
					}
				}
				catch (Exception exception)
				{
					Exception ex = (val.m_exception = exception);
				}
				try
				{
					if (!val.m_bTimedOut || val.m_exception != null)
					{
						return;
					}
					SyncDictionary<ConnectionPoolId, PM> htPM = OracleConnectionDispenser<PM, CP, PR>.m_htPM;
					if (m_cs.m_pooling && this == htPM[m_cs.m_conPoolKey] && m_pmListCP.Count > 0)
					{
						if (m_semMaxPoolSize.WaitOne(0))
						{
							PutNewPR(val, bForPoolPopulation: true);
						}
					}
					else
					{
						try
						{
							val.DisConnect(null);
						}
						catch
						{
						}
					}
				}
				finally
				{
					try
					{
						eventConCreated.Set();
					}
					catch
					{
					}
					try
					{
						eventConTimeout.Wait(val.m_conTimeout);
					}
					catch
					{
					}
					try
					{
						eventConTimeout.Dispose();
					}
					catch
					{
					}
					try
					{
						eventConCreated.Dispose();
					}
					catch
					{
					}
				}
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPRThreadFunc, ex2);
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPRThreadFunc);
				}
			}
		}

		internal PR ConnectWithNoTimeout(PR pr, string instanceName, ConnectionString csWithDiffOrNewPwd, bool bForPoolPopulation, OracleConnection connRefForCriteria)
		{
			bool bForPoolPopulation2 = !bForPoolPopulation;
			if (csWithDiffOrNewPwd == null)
			{
				pr.Connect(m_cs, bForPoolPopulation2, connRefForCriteria, instanceName);
			}
			else
			{
				pr.Connect(csWithDiffOrNewPwd, bForPoolPopulation2, connRefForCriteria, instanceName);
			}
			ProcessCriteriaCtxAndAlterSessionIfReqd(connRefForCriteria, pr);
			PutNewPR(pr, bForPoolPopulation);
			return pr;
		}

		public virtual PR CreateNewPR(int reqCount, bool bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, OracleConnection connRefForCriteria, string instanceName = null, List<string> switchFailedInstNames = null)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, Trace.GetCPInfo(null, null, instanceName, null));
			}
			PR val = null;
			try
			{
				val = new PR();
				val.m_pm = (PM)this;
				int num = 0;
				num = csWithDiffOrNewPwd?.m_connectionTimeout ?? ((m_cs.m_connectionTimeout <= 2147483) ? m_cs.m_connectionTimeout : 2147483);
				int num2 = num * 1000;
				bool flag = false;
				int num3 = 0;
				while (!flag)
				{
					if (!string.IsNullOrEmpty(m_conStrServiceName) && m_dictSvcCtx[m_conStrServiceName] != null && !m_dictSvcCtx[m_conStrServiceName].m_serviceUpEvent.IsSet)
					{
						lock (m_syncObjForDefaultSvcRelocWait)
						{
							if (m_dictSvcCtx[m_conStrServiceName] != null && !m_dictSvcCtx[m_conStrServiceName].m_serviceUpEvent.IsSet && !m_dictSvcCtx[m_conStrServiceName].m_bWaitedForSvcReloc)
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, "Waiting for Service up event in connection pool " + GetHashCode());
								}
								TimeSpan timeSpan = DateTime.Now - m_dictSvcCtx[m_conStrServiceName].m_serviceDownTime;
								TimeSpan zero = TimeSpan.Zero;
								zero = (ConfigBaseClass.s_bFromConfigSRCT ? ((!ConfigBaseClass.s_bDrainTimeoutInSRCT) ? TimeSpan.FromSeconds(ConfigBaseClass.srctOffset) : TimeSpan.FromSeconds(m_drain_timeout + ConfigBaseClass.srctOffset)) : ((m_drain_timeout == 0) ? TimeSpan.FromSeconds(Convert.ToInt32(ConfigBaseClass.m_serviceRelocationTimeout)) : TimeSpan.FromSeconds(m_drain_timeout)));
								int num4 = 0;
								if (timeSpan > TimeSpan.Zero && timeSpan < zero)
								{
									num4 = (int)(zero - timeSpan).TotalSeconds;
									if (num4 < 0)
									{
										num4 = 2147483;
									}
								}
								m_dictSvcCtx[m_conStrServiceName].m_serviceUpEvent.Wait(num4 * 1000);
								m_dictSvcCtx[m_conStrServiceName].m_bWaitedForSvcReloc = true;
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, "Finished waiting for Service up event in connection pool " + GetHashCode());
								}
							}
						}
					}
					if (num2 == 0 || bForPoolPopulation)
					{
						PR val2 = ConnectWithNoTimeout(val, instanceName, csWithDiffOrNewPwd, bForPoolPopulation, connRefForCriteria);
						flag = true;
						if (val2 != null)
						{
							return val2;
						}
						continue;
					}
					val.m_eventConCreated = new ManualResetEventSlim();
					val.m_eventConTimeout = new ManualResetEventSlim();
					val.m_conTimeout = num2;
					val.m_cs = csWithDiffOrNewPwd;
					val.m_affinityInstance = instanceName;
					val.requestingThreadId = Thread.CurrentThread.ManagedThreadId;
					ThreadPool.QueueUserWorkItem(new WaitCallback(CreateNewPRThreadFunc), new object[2]
					{
						val,
						connRefForCriteria
					});
					try
					{
						val.m_bTimedOut = !val.m_eventConCreated.Wait(num2);
					}
					finally
					{
						val.m_eventConTimeout.Set();
					}
					if (val.m_bTimedOut)
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, OracleConnection.Dump());
						}
						throw new OracleException(ResourceStringConstants.CON_TIMEOUT_EXCEEDED, string.Empty, string.Empty, string.Empty);
					}
					if (val.m_exception != null)
					{
						if (val.m_exception.Message.StartsWith("ORA-12514", StringComparison.InvariantCulture))
						{
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, "ORA-12514 in connection pool " + GetHashCode());
							}
							if (!string.IsNullOrEmpty(m_conStrServiceName) && m_dictSvcCtx[m_conStrServiceName] != null && !m_dictSvcCtx[m_conStrServiceName].m_serviceUpEvent.IsSet)
							{
								if (m_dictSvcCtx[m_conStrServiceName].m_bWaitedForSvcReloc)
								{
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, "Already WAITED for ServiceRelocationConnectionTimeout, propagate exception now for connection pool (id: " + GetHashCode() + ");\n");
									}
									throw val.m_exception;
								}
								val.m_exception = null;
								continue;
							}
							num3++;
							if (num3 < 4)
							{
								val.m_exception = null;
								if (num3 > 1)
								{
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, "ORA-12514 : Sleep for a sec in connection pool " + GetHashCode());
									}
									Thread.Sleep(1000);
								}
								continue;
							}
						}
						throw val.m_exception;
					}
					try
					{
						ProcessCriteriaCtxAndAlterSessionIfReqd(connRefForCriteria, val);
						flag = true;
						PutNewPR(val, bForPoolPopulation);
					}
					catch (OracleException)
					{
						if (val != null)
						{
							if (switchFailedInstNames != null && !switchFailedInstNames.Contains(val.m_instanceName))
							{
								switchFailedInstNames.Add(val.m_instanceName);
							}
							PutNewPR(val, bForPoolPopulation: true);
						}
						throw;
					}
				}
				int count = m_pmListPR.Count;
				if (m_cs.m_pooling && m_cs.m_incrPoolSize > 1 && count > m_cs.m_minPoolSize && count < m_cs.m_maxPoolSize && m_semPoolPopulation.WaitOne(0))
				{
					if (m_pmListPR.Count < m_cs.m_maxPoolSize)
					{
						int num5 = m_pmListPR.Count + m_cs.m_incrPoolSize;
						int num6 = m_cs.m_incrPoolSize;
						if (num5 > m_cs.m_maxPoolSize)
						{
							int num7 = num5 - m_cs.m_maxPoolSize;
							num6 -= num7;
						}
						if (num6 > 0)
						{
							string connectionClass = null;
							if (connRefForCriteria != null)
							{
								connectionClass = connRefForCriteria.m_criteriaConnCls;
							}
							PoolPopulationOption state = new PoolPopulationOption(num6, num6 + m_pmListPR.Count, m_semPoolPopulation, ignoreIncrPoolSize: false, connectionClass);
							ThreadPool.QueueUserWorkItem(new WaitCallback(PopulatePoolThreadFunc), state);
						}
						else
						{
							m_semPoolPopulation.Release();
						}
					}
					else
					{
						m_semPoolPopulation.Release();
					}
				}
				return val;
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, ex2);
				if (ex2 is OracleException)
				{
					if (((OracleException)ex2).Number == 38802 || ((OracleException)ex2).Number == 2248)
					{
						m_criteriaMapper.RemoveId(connRefForCriteria.m_criteriaEdition, 2);
					}
					if (((OracleException)ex2).Number == 38802)
					{
						throw new OracleException(-7505, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(-7505), ex2);
					}
				}
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.CreateNewPR, Trace.GetCPInfo(val as OracleConnectionImpl, null, instanceName, null));
				}
			}
		}

		public virtual PR GetUsingDiffPassword(ConnectionString csWithDiffOrNewPwd, OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetUsingDiffPassword, Trace.GetCPInfo(null, null, null, null));
			}
			PR val = null;
			try
			{
				val = CreateNewPR(1, bForPoolPopulation: false, csWithDiffOrNewPwd, connRefForCriteria);
				val.m_deletionRequestor = DeletionRequestor.None;
				lock (val)
				{
					val.m_bPutCompleted = false;
				}
				if (val != null && m_semMaxPoolSize.WaitOne(0))
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetUsingDiffPassword, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, "new1"));
					}
					return val;
				}
				val?.DisConnect(null);
				return Get(csWithDiffOrNewPwd, bGetForApp: true, connRefForCriteria);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetUsingDiffPassword, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetUsingDiffPassword, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, null));
				}
			}
		}

		public PR GetIdleConnectionToKill(TimeSpan ts, List<string> instancesToSkip = null)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetIdleConnectionToKill, Trace.GetCPInfo(null, null, null, null));
			}
			bool flag = false;
			PR val = null;
			try
			{
				if (!m_semIdleResource.WaitOne(0))
				{
					return val;
				}
				flag = true;
				List<CP> list = m_pmListCP.GetList();
				list.Sort(CPComparer.s_cpComparer);
				DateTime now = DateTime.Now;
				while (val == null)
				{
					lock (m_lockGetSync)
					{
						for (int i = 0; i < list.Count; i++)
						{
							CP val2 = list[i];
							if (instancesToSkip == null || !instancesToSkip.Contains(val2.m_instanceName))
							{
								val = val2.Get(null);
								if (val != null)
								{
									return val;
								}
							}
						}
					}
					Thread.Sleep(500);
					if (DateTime.Now - now > ts)
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetIdleConnectionToKill, OracleConnection.Dump());
						}
						throw new OracleException((m_pmListPR.Count >= m_maxPoolSize) ? ResourceStringConstants.CON_POOLED_TIMEOUT_EXCEEDED : ResourceStringConstants.CON_TIMEOUT_EXCEEDED, string.Empty, string.Empty, string.Empty);
					}
				}
				return val;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetIdleConnectionToKill, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetIdleConnectionToKill, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, null));
				}
				if (flag && val == null)
				{
					m_semIdleResource.Release();
				}
			}
		}

		internal static List<ShardRoutingCache> GetSharedShardRoutingCaches(string databaseName)
		{
			List<ShardRoutingCache> result = null;
			SyncDictionary<string, ShardRoutingCache> syncDictionary = m_shardRoutingCacheDict[databaseName.ToLowerInvariant()];
			if (syncDictionary != null)
			{
				result = syncDictionary.GetValues();
			}
			return result;
		}

		protected void CreateSharedShardRoutingCache(PR conn)
		{
			if (m_shardRoutingCache != null || conn == null || conn.ServiceName == null)
			{
				return;
			}
			string key = m_databaseName.ToLowerInvariant();
			string key2 = conn.ServiceName.ToLowerInvariant();
			SyncDictionary<string, ShardRoutingCache> syncDictionary = m_shardRoutingCacheDict[key];
			if (syncDictionary == null)
			{
				lock (m_shardRoutingCacheDict)
				{
					syncDictionary = m_shardRoutingCacheDict[key];
					if (syncDictionary == null)
					{
						syncDictionary = new SyncDictionary<string, ShardRoutingCache>();
						m_shardRoutingCacheDict[key] = syncDictionary;
					}
				}
			}
			m_shardRoutingCache = syncDictionary[key2];
			if (m_shardRoutingCache != null)
			{
				return;
			}
			lock (syncDictionary)
			{
				m_shardRoutingCache = syncDictionary[key2];
				if (m_shardRoutingCache == null)
				{
					m_shardRoutingCache = new ShardRoutingCache();
					syncDictionary[key2] = m_shardRoutingCache;
				}
			}
		}

		public string[] GetShardInstances(OracleConnection connRefForCriteria)
		{
			if (connRefForCriteria.ShardingKey == null && connRefForCriteria.SuperShardingKey == null)
			{
				return null;
			}
			return connRefForCriteria.m_shardingInstances;
		}

		public string[] GetShardInstancesEx(OracleConnection con, ref string chunkName, ref string[] readOnlyInstances, ref InstanceInfo[] instanceInfos)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetShardInstancesEx);
			}
			chunkName = null;
			readOnlyInstances = null;
			instanceInfos = null;
			if (con.ShardingKey == null && con.SuperShardingKey == null)
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetShardInstancesEx, "Exiting... no shard keys are set.");
				}
				return null;
			}
			if (!m_bReadOnlyChunkOK.HasValue || m_shardRoutingCache == null)
			{
				return null;
			}
			OracleShardingKeyImpl shardingKey = null;
			OracleShardingKeyImpl superShardingKey = null;
			if (con.ShardingKey != null)
			{
				shardingKey = con.ShardingKey.ShardingKeyInternal;
			}
			if (con.SuperShardingKey != null)
			{
				superShardingKey = con.SuperShardingKey.ShardingKeyInternal;
			}
			string[] allPriorityInstances = m_shardRoutingCache.GetAllPriorityInstances(superShardingKey, shardingKey, m_bReadOnlyChunkOK.Value, ref chunkName, ref readOnlyInstances, ref instanceInfos);
			if (allPriorityInstances == null || allPriorityInstances.Length == 0 || instanceInfos == null || instanceInfos.Length == 0)
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetShardInstancesEx, "Exiting... no topology information exist for the shard keys.");
				}
				return null;
			}
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				string text = string.Empty;
				InstanceInfo[] array = instanceInfos;
				foreach (InstanceInfo instanceInfo in array)
				{
					string text2 = $"[{instanceInfo.InstanceName}, {instanceInfo.Status}]";
					text = ((!string.IsNullOrEmpty(text)) ? (text + "," + text2) : text2);
				}
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetShardInstancesEx, $"Sharding instances (chunk={chunkName}) (instances={text})");
			}
			return allPriorityInstances;
		}

		public void OnShardingError(int errorCode, string instanceName, string chunkName)
		{
			if (m_shardRoutingCache != null)
			{
				switch (errorCode)
				{
				case 45582:
					m_shardRoutingCache.OnErrorInvalidateChunkForInstance(instanceName, chunkName);
					break;
				case 45583:
					m_shardRoutingCache.OnErrorInvalidateChunk(instanceName, chunkName);
					break;
				}
			}
		}

		public PR GetPRForSharding(ConnectionString csWithDiffOrNewPwd, string requestedServiceName, string[] instanceNames, OracleConnection connRefForCriteria, List<string> instancesToSkip = null)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				string text = string.Join(",", instanceNames);
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, text);
			}
			PR val = null;
			try
			{
				if (instanceNames == null || instanceNames.Length == 0)
				{
					return null;
				}
				foreach (string text2 in instanceNames)
				{
					if (text2 == null)
					{
						return null;
					}
				}
				string text3 = null;
				bool flag = false;
				bool flag2 = false;
				List<string> keys = m_dictDictCP.GetKeys();
				int num = 0;
				if (!string.IsNullOrEmpty(requestedServiceName))
				{
					num = keys.IndexOf(requestedServiceName);
				}
				int num2 = ((num >= 0) ? num : 0);
				RLB rLB = null;
				if (!string.IsNullOrEmpty(requestedServiceName) && m_dictSvcCtx[requestedServiceName] != null && m_dictSvcCtx[requestedServiceName].m_serviceDown)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, "MultiTenant : Service DOWN: " + requestedServiceName);
					}
					flag2 = true;
				}
				for (int j = 0; j < keys.Count; j++)
				{
					if (val != null)
					{
						break;
					}
					rLB = null;
					CP val2 = null;
					string text4 = keys[num2];
					if (!string.IsNullOrEmpty(text4) && !flag2)
					{
						int num3 = 0;
						while (num3 < instanceNames.Length && val == null)
						{
							List<string> list = new List<string>();
							bool flag3 = true;
							if (connRefForCriteria != null && connRefForCriteria.m_shardingInstanceInfos != null && connRefForCriteria.m_shardingInstanceInfos.Length == instanceNames.Length)
							{
								InstanceInfo[] shardingInstanceInfos = connRefForCriteria.m_shardingInstanceInfos;
								int priority = shardingInstanceInfos[num3].Priority;
								ChunkStatus status = shardingInstanceInfos[num3].Status;
								bool flag4 = true;
								for (int k = num3; k < instanceNames.Length && flag4; k++)
								{
									if (priority == shardingInstanceInfos[k].Priority && status == shardingInstanceInfos[k].Status)
									{
										list.Add(instanceNames[k]);
									}
									else
									{
										flag4 = false;
									}
								}
								num3 += list.Count;
								if (list.Count < 2)
								{
									flag3 = false;
								}
							}
							else
							{
								list.AddRange(instanceNames);
								num3 = instanceNames.Length;
								flag3 = false;
							}
							string text5 = null;
							if (flag3)
							{
								if (m_dictSvcCtx[text4] != null)
								{
									text5 = (m_dictSvcCtx[text4].m_databaseName + "|" + text4).ToLowerInvariant();
								}
								if (text5 != null)
								{
									rLB = RLBManager.Get(text5);
									if (rLB != null)
									{
										rLB = rLB.GetSnapshot(list);
									}
								}
							}
							int currentIndex = 0;
							bool flag5 = false;
							int num4 = 0;
							int num5 = -1;
							if (rLB != null)
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									string arg = string.Join(",", list);
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, $"Applying RLB for {arg}");
								}
								lock (m_lockGetSync)
								{
									for (int l = 0; l < rLB.m_instances.Length; l++)
									{
										if (l == 0 || flag5)
										{
											text3 = rLB.GetInstanceName(out currentIndex);
											num5 = currentIndex;
										}
										else
										{
											if (num4 >= rLB.m_instances.Length)
											{
												num4 = 0;
											}
											text3 = rLB.m_instances[num4];
											num5 = num4;
										}
										if (!string.IsNullOrEmpty(text3) && m_dictDictCP[keys[num2]] != null)
										{
											val2 = m_dictDictCP[keys[num2]][text3];
											if (val2 != null && !val2.m_bInstanceDown && (m_dictSvcCtx[text4] == null || m_dictSvcCtx[text4].m_serviceMemberDownInstNames.IndexOf(val2.m_instanceName) == -1) && (instancesToSkip == null || !instancesToSkip.Contains(val2.m_instanceName)))
											{
												val = (((m_cs.m_orclCredential != null && m_cs.m_orclCredential.m_bProxyUserIdSet) || m_cs.m_bProxyUserIdSet) ? val2.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val2.Get(connRefForCriteria));
											}
											else if (ProviderConfig.m_bTraceLevelPrivate && val2 != null)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, $"MultiTenant : Skipping pool with service: {val2.m_serviceName}, instance: {val2.m_instanceName} (3)");
											}
										}
										if (val != null)
										{
											break;
										}
										if (val2 != null && !val2.HasValidConnections)
										{
											RemoveAndRedistribute(rLB, val2, num5);
											flag5 = true;
											continue;
										}
										if (l == 0)
										{
											num4 = ((currentIndex == 0) ? (num4 + 1) : 0);
											continue;
										}
										num4++;
										if (num4 == currentIndex)
										{
											num4++;
										}
									}
								}
							}
							else
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									string arg2 = string.Join(",", list);
									Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, $"Iterating through CP for {arg2}");
								}
								lock (m_lockGetSync)
								{
									for (int m = 0; m < list.Count; m++)
									{
										val2 = m_dictDictCP[keys[num2].ToLowerInvariant()][list[m].ToLowerInvariant()];
										if (val2 != null && !val2.m_bInstanceDown && (m_dictSvcCtx[text4] == null || m_dictSvcCtx[text4].m_serviceMemberDownInstNames.IndexOf(val2.m_instanceName) == -1) && (instancesToSkip == null || !instancesToSkip.Contains(val2.m_instanceName)))
										{
											val = ((!(((m_cs.m_orclCredential == null || !m_cs.m_orclCredential.m_bProxyUserIdSet) && !m_cs.m_bProxyUserIdSet) || flag)) ? val2.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val2.Get(connRefForCriteria));
										}
										else if (ProviderConfig.m_bTraceLevelPrivate && val2 != null)
										{
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, $"MultiTenant : Skipping pool with service: {val2.m_serviceName}, instance: {val2.m_instanceName}");
										}
										if (val != null)
										{
											break;
										}
									}
								}
							}
							if (val != null && ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, (rLB == null) ? "pm:get:rro1" : "get:rlb1"));
							}
						}
					}
					if (val == null)
					{
						num2++;
						if (num2 == keys.Count)
						{
							num2 = 0;
						}
					}
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRForSharding, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, (val != null) ? $"Multitenant: Found a connection. ServiceName: {val.ServiceName}, InstanceName: {val.m_instanceName}" : "pr not found"));
				}
			}
			return val;
		}

		public PR GetPRWithMatchingServiceOrInstance(ConnectionString csWithDiffOrNewPwd, List<string> services, string serviceName, string instanceName, OracleConnection connRefForCriteria, List<string> instancesToSkip = null)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRWithMatchingServiceOrInstance);
			}
			PR val = null;
			CP val2 = null;
			bool flag = false;
			try
			{
				lock (m_lockGetSync)
				{
					if (m_dictDictCP[serviceName.ToLowerInvariant()] != null)
					{
						val2 = m_dictDictCP[serviceName.ToLowerInvariant()][instanceName.ToLowerInvariant()];
						if (val2 != null)
						{
							if (!val2.m_bInstanceDown && (instancesToSkip == null || !instancesToSkip.Contains(val2.m_instanceName)))
							{
								CP val3 = val2;
								if (val3 != null)
								{
									val = (((m_cs.m_orclCredential != null && m_cs.m_orclCredential.m_bProxyUserIdSet) || m_cs.m_bProxyUserIdSet) ? val3.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val3.Get(connRefForCriteria));
								}
								if (val != null)
								{
									return val;
								}
							}
							else
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRWithMatchingServiceOrInstance, $"Service {serviceName} is DOWN on Instance {instanceName}. Not dispensing connections from this pool.");
								}
								flag = true;
							}
						}
					}
					int num = services.IndexOf(serviceName);
					int num2 = ((num > 0) ? num : 0);
					for (int i = 0; i < services.Count; i++)
					{
						if (m_dictDictCP[services[num2]] == null)
						{
							continue;
						}
						if (i == 0 && num >= 0)
						{
							List<CP> list = ((m_dictDictCP[services[num2].ToLowerInvariant()] != null) ? m_dictDictCP[services[num2].ToLowerInvariant()].GetValues() : null);
							if (list != null)
							{
								for (int j = 0; j < list.Count; j++)
								{
									CP val4 = list[j];
									if (val4 == val2 && !val4.m_bInstanceDown && (instancesToSkip == null || !instancesToSkip.Contains(val4.m_instanceName)))
									{
										if (val4 != null)
										{
											val = (((m_cs.m_orclCredential != null && m_cs.m_orclCredential.m_bProxyUserIdSet) || m_cs.m_bProxyUserIdSet) ? val4.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val4.Get(connRefForCriteria));
										}
										if (val != null)
										{
											return val;
										}
									}
								}
							}
						}
						else
						{
							if (flag)
							{
								break;
							}
							CP val5 = m_dictDictCP[services[num2].ToLowerInvariant()][instanceName];
							if (val5 != null)
							{
								val = (((m_cs.m_orclCredential != null && m_cs.m_orclCredential.m_bProxyUserIdSet) || m_cs.m_bProxyUserIdSet) ? val5.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val5.Get(connRefForCriteria));
							}
						}
						if (val != null)
						{
							return val;
						}
						num2++;
						if (num2 == services.Count)
						{
							num2 = 0;
						}
					}
				}
				return val;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRWithMatchingServiceOrInstance, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, (val != null) ? $"Multitenant: Found a connection. ServiceName: {val.ServiceName}, InstanceName: {val.m_instanceName}" : "pr not found"));
				}
			}
		}

		private PR DestoryAndReplace(ConnectionString csWithDiffOrNewPwd, OracleConnection connRefForCriteria, string affinityInstanceName, List<string> switchFailedInstNames = null)
		{
			PR val = null;
			lock (m_lockGetSync)
			{
				for (int i = 0; i < m_pmListCP.Count; i++)
				{
					CP val2 = m_pmListCP[i];
					if (val2 != null)
					{
						val = (((m_cs.m_orclCredential != null && m_cs.m_orclCredential.m_bProxyUserIdSet) || m_cs.m_bProxyUserIdSet) ? val2.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val2.Get(connRefForCriteria));
					}
					if (val != null)
					{
						break;
					}
				}
			}
			PR val3 = val;
			val = CreateNewPR(1, bForPoolPopulation: false, csWithDiffOrNewPwd, connRefForCriteria, affinityInstanceName, switchFailedInstNames);
			if (val != null)
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					string str = $"({val3.m_endUserSessionId}:{val3.m_endUserSerialNum})";
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.DestroyAndReplace, str + " : (HA) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
				}
				val3.m_deletionRequestor = DeletionRequestor.HA;
				val3.m_bClosedWithReplacement = true;
				Put(val3, null);
				val3.m_bClosedWithReplacement = false;
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetPRWithMatchingServiceOrInstance, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, $"pm:get:killed(sessid{val3.m_endUserSessionId.ToString()}:{val3.m_endUserSerialNum.ToString()};inst={val3.m_instanceName})"));
				}
			}
			return val;
		}

		public virtual PR Get(ConnectionString csWithDiffOrNewPwd, bool bGetForApp, OracleConnection connRefForCriteria, string affinityInstanceName = null, bool bForceMatch = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(null, null, affinityInstanceName, null) + "(bForceMatch={0})", bForceMatch.ToString().Substring(0, 1));
			}
			PR val = null;
			string text = null;
			int num = 0;
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			bool flag4 = false;
			bool flag5 = false;
			bool flag6 = false;
			bool flag7 = false;
			TimeSpan timeSpan = m_timeoutValue;
			DateTime now = DateTime.Now;
			int num2 = 0;
			List<string> list = null;
			if (connRefForCriteria != null && !string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName))
			{
				list = new List<string>();
			}
			try
			{
				if (m_cs.m_drcpEnabled == DrcpType.True && !string.IsNullOrEmpty(m_cs.m_proxyUserId) && m_cs.m_securedPassword != null)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(28150));
				}
				if (connRefForCriteria != null)
				{
					if (m_cs.m_drcpEnabled == DrcpType.False && !string.IsNullOrEmpty(connRefForCriteria.m_criteriaConnCls))
					{
						throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(-7601, "DRCPConnectionClass", "DRCP"));
					}
					m_criteriaMapper.AssignId(connRefForCriteria);
				}
				while (val == null && num2 <= 1)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : Searching for a idle connection, retryCountWithoutAffinity: " + num2);
					}
					try
					{
						flag = false;
						flag2 = false;
						flag3 = false;
						flag4 = false;
						flag5 = false;
						if (!flag6)
						{
							num = WaitHandle.WaitAny(m_IdleAndIncrHandles, timeSpan);
							switch (num)
							{
							case 0:
								flag = true;
								break;
							case 1:
								flag2 = true;
								break;
							}
						}
						else
						{
							num = WaitHandle.WaitAny(m_IdleAndMaxHandles, timeSpan);
							switch (num)
							{
							case 0:
								flag = true;
								break;
							case 1:
								flag3 = true;
								break;
							}
						}
						ProcessCriteriaCtx_NonEnlistedConnection(ref connRefForCriteria);
						switch (num)
						{
						case 0:
							try
							{
								string[] array = null;
								bool flag8 = false;
								string text2 = m_conStrServiceName;
								if (connRefForCriteria != null && !string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName))
								{
									text2 = connRefForCriteria.m_criteriaServiceName;
								}
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : Searching for a idle connection. Service Name: " + text2);
								}
								if (connRefForCriteria != null)
								{
									flag8 = connRefForCriteria.m_shardKey != null || connRefForCriteria.m_shardGroupKey != null;
								}
								if (!(connRefForCriteria != null && flag8))
								{
									array = new string[1]
									{
										affinityInstanceName
									};
								}
								else
								{
									array = GetShardInstances(connRefForCriteria);
									if (array != null)
									{
										affinityInstanceName = array[0];
									}
									else
									{
										bool flag9 = false;
										affinityInstanceName = null;
										bool flag10 = false;
										if (!string.IsNullOrEmpty(text2))
										{
											if (m_dictSvcCtx[text2] != null && m_dictSvcCtx[text2].m_serviceDown)
											{
												if (ProviderConfig.m_bTraceLevelPrivate)
												{
													Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : Service DOWN: " + text2);
												}
												flag9 = true;
											}
											if (!string.IsNullOrEmpty(affinityInstanceName) && m_dictSvcCtx[text2] != null && m_dictSvcCtx[text2].m_serviceMemberDownInstNames.IndexOf(affinityInstanceName) >= 0)
											{
												if (ProviderConfig.m_bTraceLevelPrivate)
												{
													Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"MultiTenant : Service Member DOWN {text2} on instance {affinityInstanceName}");
												}
												flag10 = true;
											}
										}
										if (!flag9)
										{
											string text3 = null;
											if (!flag8)
											{
												if (!flag10 && (list == null || list.Count == 0))
												{
													text3 = affinityInstanceName;
												}
												else
												{
													if (m_dictSvcCtx[text2] != null)
													{
														text3 = GetInstanceNameToConnect(text2, list, out var _);
													}
													if (string.IsNullOrEmpty(text3) && connRefForCriteria.m_serviceSwitchRequested)
													{
														throw new OracleException(-7505, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(-7505));
													}
												}
											}
											val = GetNew(csWithDiffOrNewPwd, connRefForCriteria, text3, list);
											if (val != null)
											{
												m_semIdleResource.Release();
												return val;
											}
											val = DestoryAndReplace(csWithDiffOrNewPwd, connRefForCriteria, text3, list);
											if (val != null)
											{
												return val;
											}
										}
									}
								}
								if (flag8)
								{
									if (!string.IsNullOrEmpty(text2))
									{
										val = GetPRForSharding(csWithDiffOrNewPwd, text2, array, connRefForCriteria, list);
										if (val != null)
										{
											affinityInstanceName = val.m_instanceName;
										}
									}
								}
								else
								{
									lock (m_lockGetSync)
									{
										int num3 = 0;
										while (val == null && num3 < array.Length)
										{
											affinityInstanceName = array[num3];
											if (affinityInstanceName != null && !string.IsNullOrEmpty(text2))
											{
												List<string> keys = m_dictDictCP.GetKeys();
												val = GetPRWithMatchingServiceOrInstance(csWithDiffOrNewPwd, keys, text2, affinityInstanceName, connRefForCriteria, list);
											}
											num3++;
										}
									}
								}
								if (affinityInstanceName != null)
								{
									bool flag11 = false;
									bool flag12 = false;
									if (!string.IsNullOrEmpty(text2))
									{
										if (m_dictSvcCtx[text2] != null && m_dictSvcCtx[text2].m_serviceDown)
										{
											if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : Service DOWN: " + text2);
											}
											flag11 = true;
										}
										if (m_dictSvcCtx[text2] != null && m_dictSvcCtx[text2].m_serviceMemberDownInstNames.IndexOf(affinityInstanceName) >= 0)
										{
											if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"MultiTenant : Service Member DOWN {text2} on instance {affinityInstanceName} (1)");
											}
											flag12 = true;
										}
										if (val == null && !flag11)
										{
											List<string> keys2 = m_dictDictCP.GetKeys();
											val = GetPRWithMatchingServiceOrInstance(csWithDiffOrNewPwd, keys2, text2, affinityInstanceName, connRefForCriteria, list);
										}
										if (val == null && !flag11 && !flag8)
										{
											lock (m_lockGetSync)
											{
												for (int i = 0; i < m_pmListCP.Count; i++)
												{
													CP val2 = m_pmListCP[i];
													if (val2 != null)
													{
														if (val2.m_serviceName == text2 || val2.m_instanceName == affinityInstanceName || val2.m_bInstanceDown || (m_dictSvcCtx[text2] != null && m_dictSvcCtx[text2].m_serviceMemberDownInstNames.IndexOf(val2.m_instanceName) >= 0) || (list != null && list.Contains(val2.m_instanceName)))
														{
															if (ProviderConfig.m_bTraceLevelPrivate)
															{
																Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"Multitenant : Skipping pool with service: {val2.m_serviceName}, instance: {val2.m_instanceName} (2)");
															}
															continue;
														}
														val = (((m_cs.m_orclCredential != null && m_cs.m_orclCredential.m_bProxyUserIdSet) || m_cs.m_bProxyUserIdSet) ? val2.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val2.Get(connRefForCriteria));
													}
													if (val != null)
													{
														break;
													}
												}
											}
										}
										if (val != null)
										{
											if (val.m_instanceName != affinityInstanceName && !flag12)
											{
												PR val3 = val;
												val = null;
												try
												{
													val = CreateNewPR(1, bForPoolPopulation: false, csWithDiffOrNewPwd, connRefForCriteria, affinityInstanceName, list);
													if (val != null)
													{
														if (ProviderConfig.m_bTraceLevelPrivate)
														{
															string str = $"({val3.m_endUserSessionId.ToString()}:{val3.m_endUserSerialNum})";
															Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, str + " : (HA) (1) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
														}
														val3.m_deletionRequestor = DeletionRequestor.HA;
														val3.m_bClosedWithReplacement = true;
														Put(val3, null);
														val3.m_bClosedWithReplacement = false;
														if (ProviderConfig.m_bTraceLevelPrivate)
														{
															Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, $"pm:get:killed(sessid{val3.m_endUserSessionId.ToString()}:{val3.m_endUserSerialNum.ToString()};inst={val3.m_instanceName})"));
														}
													}
												}
												catch (Exception ex)
												{
													if (ex.InnerException == null || !(ex.InnerException is OracleException) || ((OracleException)ex.InnerException).Number != 44787)
													{
														throw;
													}
													if (ProviderConfig.m_bTraceLevelPrivate)
													{
														Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : ORA error 44787. Lets swallow this error and use the idle connection instead - 1\n" + ex.ToString());
													}
													val = val3;
													val3 = null;
												}
											}
											if (val != null && ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, "pm:get:reg1"));
											}
										}
										if (val == null && ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(null, null, affinityInstanceName, "pm.get:reg1:nothing"));
										}
									}
									if (val == null)
									{
										string text4 = null;
										if (!flag8)
										{
											if (!flag12 && (list == null || list.Count == 0))
											{
												text4 = affinityInstanceName;
											}
											else
											{
												text4 = GetInstanceNameToConnect(text2, list, out var _);
												if (string.IsNullOrEmpty(text4) && connRefForCriteria.m_serviceSwitchRequested)
												{
													throw new OracleException(-7505, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(-7505));
												}
											}
										}
										if (flag)
										{
											m_semIdleResource.Release();
											flag = false;
										}
										val = GetNew(csWithDiffOrNewPwd, connRefForCriteria, text4, list);
										if (val != null)
										{
											if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, "pm:get:new2"));
											}
											flag5 = true;
										}
										else if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(null, null, affinityInstanceName, "pm:get:new2:nothing"));
										}
										if (val == null)
										{
											PR val4 = null;
											timeSpan = m_timeoutValue - (DateTime.Now - now);
											val4 = GetIdleConnectionToKill(timeSpan, list);
											if (val4 != null)
											{
												if (flag12)
												{
													val = val4;
													val4 = null;
												}
												else
												{
													try
													{
														val = CreateNewPR(1, bForPoolPopulation: false, csWithDiffOrNewPwd, connRefForCriteria, text4, list);
														if (val != null)
														{
															if (ProviderConfig.m_bTraceLevelPrivate)
															{
																string str2 = $"({val4.m_endUserSessionId}:{val4.m_endUserSerialNum})";
																Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, str2 + " : (HA) (2) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
															}
															val4.m_deletionRequestor = DeletionRequestor.HA;
															val4.m_bClosedWithReplacement = true;
															Put(val4, null);
															val4.m_bClosedWithReplacement = false;
															if (ProviderConfig.m_bTraceLevelPrivate)
															{
																Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, $"pm:get:killed(sessid{val4.m_endUserSessionId.ToString()}:{val4.m_endUserSerialNum.ToString()};inst={val4.m_instanceName})"));
															}
														}
													}
													catch (Exception ex2)
													{
														if (ex2.InnerException == null || !(ex2.InnerException is OracleException) || ((OracleException)ex2.InnerException).Number != 44787)
														{
															throw;
														}
														if (ProviderConfig.m_bTraceLevelPrivate)
														{
															Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : ORA error 44787. Lets swallow this error and use the idle connection instead - 2\n" + ex2.ToString());
														}
														val = val4;
														val4 = null;
													}
												}
											}
											else if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(null, null, affinityInstanceName, "pm:get:kill:nothing"));
											}
										}
									}
								}
								if (val != null || flag8)
								{
									break;
								}
								bool flag13 = false;
								bool flag14 = false;
								List<string> keys3 = m_dictDictCP.GetKeys();
								int num4 = 0;
								if (!string.IsNullOrEmpty(text2))
								{
									num4 = keys3.IndexOf(text2);
								}
								int num5 = ((num4 >= 0) ? num4 : 0);
								int num6 = 0;
								RLB rLB = null;
								if (!string.IsNullOrEmpty(text2))
								{
									if (m_dictSvcCtx[text2] != null && m_dictSvcCtx[text2].m_serviceDown)
									{
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : Service DOWN: " + text2);
										}
										flag14 = true;
									}
									if (!string.IsNullOrEmpty(affinityInstanceName) && m_dictSvcCtx[text2] != null && m_dictSvcCtx[text2].m_serviceMemberDownInstNames.IndexOf(affinityInstanceName) >= 0)
									{
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"MultiTenant : Service Member DOWN {text2} on instance {affinityInstanceName}");
										}
										flag13 = true;
									}
								}
								while (val == null)
								{
									rLB = null;
									CP val5 = null;
									if (m_timeoutValue < DateTime.Now - now)
									{
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, OracleConnection.Dump());
										}
										throw new OracleException((m_pmListPR.Count >= m_maxPoolSize) ? ResourceStringConstants.CON_POOLED_TIMEOUT_EXCEEDED : ResourceStringConstants.CON_TIMEOUT_EXCEEDED, string.Empty, string.Empty, string.Empty);
									}
									if (!flag)
									{
										flag = m_semIdleResource.WaitOne(0);
									}
									if (flag)
									{
										string text5 = keys3[num5];
										if (!string.IsNullOrEmpty(text5) && !flag14)
										{
											string text6 = null;
											if (m_dictSvcCtx[text5] != null)
											{
												text6 = (m_dictSvcCtx[text5].m_databaseName + "|" + text5).ToLowerInvariant();
											}
											if (text6 != null)
											{
												rLB = RLBManager.Get(text6);
											}
											int currentIndex = m_dictSvcCtx[keys3[num5]].m_roundRobin.NextValue();
											int index = currentIndex;
											bool flag15 = false;
											int num7 = 0;
											int num8 = -1;
											if (rLB != null)
											{
												lock (m_lockGetSync)
												{
													for (int j = 0; j < rLB.m_instances.Length; j++)
													{
														if (j == 0 || flag15)
														{
															text = rLB.GetInstanceName(out currentIndex);
															num8 = currentIndex;
														}
														else
														{
															if (num7 >= rLB.m_instances.Length)
															{
																num7 = 0;
															}
															text = rLB.m_instances[num7];
															num8 = num7;
														}
														if (!string.IsNullOrEmpty(text) && m_dictDictCP[keys3[num5]] != null)
														{
															val5 = m_dictDictCP[keys3[num5]][text];
															if (val5 != null && !val5.m_bInstanceDown && (m_dictSvcCtx[text5] == null || m_dictSvcCtx[text5].m_serviceMemberDownInstNames.IndexOf(val5.m_instanceName) == -1) && (list == null || !list.Contains(val5.m_instanceName)))
															{
																val = ((!(((m_cs.m_orclCredential == null || !m_cs.m_orclCredential.m_bProxyUserIdSet) && !m_cs.m_bProxyUserIdSet) || flag7)) ? val5.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val5.Get(connRefForCriteria));
															}
															else if (ProviderConfig.m_bTraceLevelPrivate && val5 != null)
															{
																Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"MultiTenant : Skipping pool with service: {val5.m_serviceName}, instance: {val5.m_instanceName} (3)");
															}
														}
														if (val != null)
														{
															if (text != null && val.m_instanceName != text)
															{
																m_rlbMissCount++;
																if (m_rlbMissCount >= 2000)
																{
																	ThreadPool.QueueUserWorkItem(new WaitCallback(RLBGravitateThreadFunc), new object[3]
																	{
																		0,
																		val.ServiceName,
																		m_drcpConnectionClass
																	});
																	m_rlbMissCount = 0;
																}
															}
															break;
														}
														if (val5 != null && !val5.HasValidConnections)
														{
															RemoveAndRedistribute(rLB, val5, num8);
															flag15 = true;
															continue;
														}
														if (j == 0)
														{
															num7 = ((currentIndex == 0) ? (num7 + 1) : 0);
															continue;
														}
														num7++;
														if (num7 == currentIndex)
														{
															num7++;
														}
													}
												}
											}
											else
											{
												lock (m_lockGetSync)
												{
													List<CP> values = m_dictDictCP[keys3[num5].ToLowerInvariant()].GetValues();
													for (int k = 0; k < values.Count; k++)
													{
														val5 = values[index];
														if (val5 != null && !val5.m_bInstanceDown && (m_dictSvcCtx[text5] == null || m_dictSvcCtx[text5].m_serviceMemberDownInstNames.IndexOf(val5.m_instanceName) == -1) && (list == null || !list.Contains(val5.m_instanceName)))
														{
															val = ((!(((m_cs.m_orclCredential == null || !m_cs.m_orclCredential.m_bProxyUserIdSet) && !m_cs.m_bProxyUserIdSet) || flag7)) ? val5.GetProxy(csWithDiffOrNewPwd, connRefForCriteria) : val5.Get(connRefForCriteria));
														}
														else if (ProviderConfig.m_bTraceLevelPrivate && val5 != null)
														{
															Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"MultiTenant : Skipping pool with service: {val5.m_serviceName}, instance: {val5.m_instanceName}");
														}
														if (val == null)
														{
															index = m_dictSvcCtx[keys3[num5]].m_roundRobin.NextValue();
															continue;
														}
														break;
													}
												}
											}
											if (val != null && ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, (rLB == null) ? "pm:get:rro1" : "get:rlb1"));
											}
										}
									}
									if (val == null)
									{
										num5++;
										num6++;
										if (num5 == keys3.Count)
										{
											num5 = 0;
										}
										if (num6 == keys3.Count)
										{
											string text7 = null;
											if (!flag8)
											{
												if (!flag13 && (list == null || list.Count == 0))
												{
													text7 = affinityInstanceName;
												}
												else
												{
													text7 = GetInstanceNameToConnect(text2, list, out var _);
													if (string.IsNullOrEmpty(text7) && connRefForCriteria.m_serviceSwitchRequested)
													{
														throw new OracleException(-7505, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(-7505));
													}
												}
											}
											if (flag)
											{
												m_semIdleResource.Release();
												flag = false;
											}
											val = GetNew(csWithDiffOrNewPwd, connRefForCriteria, text7, list);
											if (val != null)
											{
												flag5 = true;
											}
											else
											{
												PR val6 = null;
												timeSpan = m_timeoutValue - (DateTime.Now - now);
												val6 = GetIdleConnectionToKill(timeSpan, list);
												if (val6 != null)
												{
													if (flag13)
													{
														val = val6;
														val6 = null;
													}
													else
													{
														if (ProviderConfig.m_bTraceLevelPrivate)
														{
															string str3 = $"({val6.m_endUserSessionId}:{val6.m_endUserSerialNum})";
															Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, str3 + " : (HA) (3) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
														}
														val6.m_deletionRequestor = DeletionRequestor.HA;
														val6.m_bClosedWithReplacement = true;
														Put(val6, null);
														try
														{
															val = CreateNewPR(1, bForPoolPopulation: false, csWithDiffOrNewPwd, connRefForCriteria, text7, list);
														}
														catch (Exception ex3)
														{
															if (ProviderConfig.m_bTraceLevelPrivate)
															{
																Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, ex3.ToString());
															}
															try
															{
																m_currentMaxSemCount = m_semMaxPoolSize.Release();
															}
															catch
															{
																if (ProviderConfig.m_bTraceLevelPrivate)
																{
																	Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "m_semMaxPoolSize.Release() threw exception with count = " + m_currentMaxSemCount);
																}
																throw new Exception("m_semMaxPoolSize.Release() threw exception with count = " + m_currentMaxSemCount);
															}
															throw;
														}
														val6.m_bClosedWithReplacement = false;
													}
													if (val != null)
													{
														break;
													}
												}
											}
											flag7 = true;
										}
									}
									if (val == null)
									{
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "unable to get a connection from the pool.. retrying");
										}
										timeSpan = m_timeoutValue - (DateTime.Now - now);
									}
								}
								if (val != null && ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, (rLB == null) ? "pm:get:rro2" : "pm:get:rlb2"));
								}
							}
							finally
							{
								if (flag && (val == null || flag4 || flag5))
								{
									m_currentIdleSemCount = m_semIdleResource.Release();
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"PM.Get() : Idle Sempahore count={m_currentIdleSemCount}");
									flag = false;
								}
							}
							break;
						case 1:
							try
							{
								if (!flag3)
								{
									flag3 = m_semMaxPoolSize.WaitOne(0);
								}
								if (!flag2)
								{
									flag2 = m_semIncrPoolSize.WaitOne(0);
								}
								if (flag3 && flag2)
								{
									bool flag16 = false;
									string[] array2 = null;
									if (connRefForCriteria != null)
									{
										flag16 = connRefForCriteria.m_shardKey != null || connRefForCriteria.m_shardGroupKey != null;
									}
									if (connRefForCriteria != null && flag16)
									{
										array2 = GetShardInstances(connRefForCriteria);
										affinityInstanceName = ((array2 == null) ? null : array2[0]);
									}
									bool flag17 = false;
									string text8 = m_conStrServiceName;
									if (connRefForCriteria != null && !string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName))
									{
										text8 = connRefForCriteria.m_criteriaServiceName;
									}
									if (!string.IsNullOrEmpty(affinityInstanceName) && !string.IsNullOrEmpty(text8) && m_dictSvcCtx[text8] != null && m_dictSvcCtx[text8].m_serviceMemberDownInstNames.IndexOf(affinityInstanceName) >= 0)
									{
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"MultiTenant : Service Member DOWN {text8} on affinity instance {affinityInstanceName}");
										}
										flag17 = true;
									}
									string text9 = null;
									if (!flag16)
									{
										if (!flag17 && (list == null || list.Count == 0))
										{
											text9 = affinityInstanceName;
										}
										else
										{
											bool firstConn4 = false;
											text9 = GetInstanceNameToConnect(text8, list, out firstConn4);
											if (!(!string.IsNullOrEmpty(text9) || firstConn4) && connRefForCriteria.m_serviceSwitchRequested)
											{
												throw new OracleException(-7505, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(-7505));
											}
										}
									}
									val = CreateNewPR(1, bForPoolPopulation: false, csWithDiffOrNewPwd, connRefForCriteria, text9, list);
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, text9, "pm:get:new3"));
									}
									if (val == null)
									{
									}
								}
								else
								{
									flag6 = true;
									timeSpan = m_timeoutValue - (DateTime.Now - now);
								}
							}
							finally
							{
								if (flag2)
								{
									try
									{
										m_currentIncrSemCount = m_semIncrPoolSize.Release();
									}
									catch
									{
										throw new Exception("m_semIncrPoolSize.Release1() threw exception with count = " + m_currentIncrSemCount);
									}
									flag2 = false;
								}
								if ((val == null || flag4) && flag3)
								{
									try
									{
										m_currentMaxSemCount = m_semMaxPoolSize.Release();
									}
									catch
									{
										throw new Exception("m_semMaxPoolSize.Release() threw exception with count = " + m_currentMaxSemCount);
									}
									flag3 = false;
								}
							}
							break;
						case 258:
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, OracleConnection.Dump());
							}
							throw new OracleException((m_pmListPR.Count >= m_maxPoolSize) ? ResourceStringConstants.CON_POOLED_TIMEOUT_EXCEEDED : ResourceStringConstants.CON_TIMEOUT_EXCEEDED, string.Empty, string.Empty, string.Empty);
						}
					}
					catch (OracleException ex4)
					{
						if (ex4.Number == 12521)
						{
							affinityInstanceName = null;
							num2++;
							if (num2 > 1)
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									string text10 = $"(ERROR)(ERROR=12521)(RETRY_COUNT={num2})";
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, text10);
								}
								throw ex4;
							}
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								string text11 = $"(RETRY)(ERROR=12521)(RETRY_COUNT={num2})";
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Error, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, text11);
							}
							continue;
						}
						if (ex4.Number == 38802 || ex4.Number == 2248)
						{
							m_criteriaMapper.RemoveId(connRefForCriteria.m_criteriaEdition, 2);
							throw ex4;
						}
						if (ex4.InnerException != null && ex4.InnerException is OracleException && ((OracleException)ex4.InnerException).Number == 44787)
						{
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : ORA error 44787. Try to get another connection - 1\n" + ex4.ToString());
							}
							if (DateTime.Now - now > m_timeoutValue)
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, OracleConnection.Dump());
								}
								throw new OracleException(ResourceStringConstants.CON_TIMEOUT_EXCEEDED, string.Empty, string.Empty, string.Empty);
							}
							timeSpan = m_timeoutValue - (DateTime.Now - now);
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : Time Remaining to find a connection - 1: " + timeSpan);
							}
							continue;
						}
						throw ex4;
					}
					finally
					{
						if (val != null)
						{
							lock (val)
							{
								if (bGetForApp)
								{
									val.m_bCheckedOutByApp = true;
								}
								else
								{
									val.m_bCheckedOutByDTC = true;
								}
								val.m_bPutCompleted = false;
								if (val.m_pm.m_cs.m_drcpEnabled == DrcpType.True)
								{
									_ = val.bDRCPServerProcessAttached;
								}
							}
							string serviceName = val.ServiceName;
							if (connRefForCriteria != null && val.m_bCheckIfAlterSessionReqd)
							{
								try
								{
									bool[] array3 = val.ProcessCriteriaCtx(connRefForCriteria);
									if (array3 != null && (array3[0] || array3[1]))
									{
										lock (val)
										{
											val.AlterSession(array3, connRefForCriteria);
										}
									}
								}
								catch (Exception ex5)
								{
									if (ex5.InnerException == null || !(ex5.InnerException is OracleException) || ((OracleException)ex5.InnerException).Number != 44787)
									{
										throw;
									}
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : ORA error 44787. Try to get another connection - 2.\n" + ex5.ToString());
									}
									if (val != null)
									{
										if (!string.IsNullOrEmpty(val.m_instanceName) && list != null && !list.Contains(val.m_instanceName))
										{
											list.Add(val.m_instanceName);
										}
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, $"MultiTenant : Placing the connection back. Conn ID = {val.m_endUserSessionId} , Service Name = {val.ServiceName} , PDB Name = {val.PdbName} , Edition Name = {val.EditionName} , DBInst = {val.m_instanceName}");
										}
										Put(val, connRefForCriteria);
										val = null;
									}
									if (DateTime.Now - now > m_timeoutValue)
									{
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, OracleConnection.Dump());
										}
										throw new OracleException(ResourceStringConstants.CON_TIMEOUT_EXCEEDED, string.Empty, string.Empty, string.Empty);
									}
									timeSpan = m_timeoutValue - (DateTime.Now - now);
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, "MultiTenant : Time Remaining to find a connection - 2: " + timeSpan);
									}
								}
								if (val != null && !val.ServiceName.Equals(serviceName, StringComparison.InvariantCultureIgnoreCase))
								{
									CreateServiceCtx(val);
									bool bForPoolPopulation = false;
									bool migratePR = true;
									AddPRToPool(val, bForPoolPopulation, migratePR);
								}
							}
						}
					}
				}
				return val;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					string text12 = "null";
					if (val != null)
					{
						text12 = ((!(val.m_instanceName == affinityInstanceName)) ? "bMatchFound=F" : "bMatchFound=T");
					}
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(val as OracleConnectionImpl, null, affinityInstanceName, null) + "PM.Get(aff={0};force={1}) returning ({2})", affinityInstanceName, bForceMatch.ToString().Substring(0, 1), text12);
				}
			}
		}

		internal string GetInstanceNameToConnect(string requestedServiceName, List<string> instancesToSkip, out bool firstConn)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetInstanceNameToConnect);
			}
			RLB rLB = null;
			string text = null;
			string text2 = null;
			int currentIndex = 0;
			int num = 0;
			firstConn = false;
			if (!string.IsNullOrEmpty(requestedServiceName) && m_dictSvcCtx[requestedServiceName] != null)
			{
				text = (m_dictSvcCtx[requestedServiceName].m_databaseName + "|" + m_dictSvcCtx[requestedServiceName].m_serviceName).ToLowerInvariant();
			}
			if (text != null)
			{
				rLB = RLBManager.Get(text);
			}
			if (rLB != null)
			{
				for (int i = 0; i < rLB.m_instances.Length; i++)
				{
					if (i == 0)
					{
						currentIndex = 0;
						num = 0;
						text2 = rLB.GetInstanceName(out currentIndex);
					}
					else
					{
						if (num >= rLB.m_instances.Length)
						{
							num = 0;
						}
						text2 = rLB.m_instances[num];
					}
					if (!m_dictSvcCtx[requestedServiceName].m_serviceMemberDownInstNames.GetList().Contains(text2) && (instancesToSkip == null || !instancesToSkip.Contains(text2)))
					{
						break;
					}
					text2 = null;
					if (i == 0)
					{
						num = ((currentIndex == 0) ? (num + 1) : 0);
						continue;
					}
					num++;
					if (num == currentIndex)
					{
						num++;
					}
				}
			}
			else if (m_pmListCP != null && m_pmListCP.Count > 0)
			{
				for (int j = 0; j < m_pmListCP.Count; j++)
				{
					text2 = m_pmListCP[j].m_instanceName;
					if ((m_dictSvcCtx[requestedServiceName] == null || (m_dictSvcCtx[requestedServiceName] != null && !m_dictSvcCtx[requestedServiceName].m_serviceMemberDownInstNames.GetList().Contains(text2))) && (instancesToSkip == null || !instancesToSkip.Contains(text2)))
					{
						break;
					}
					text2 = null;
				}
			}
			else if (instancesToSkip != null && instancesToSkip.Count > 0)
			{
				firstConn = false;
			}
			else
			{
				firstConn = true;
			}
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetInstanceNameToConnect, $"MultiTenant : Returning inst name: {text2}, firstConn: {firstConn}");
			}
			return text2;
		}

		private List<string> GetInstNames()
		{
			List<CP> list = m_pmListCP.GetList();
			List<string> list2 = new List<string>();
			for (int i = 0; i < list.Count; i++)
			{
				if (!list2.Contains(list[i].m_instanceName))
				{
					list2.Add(list[i].m_instanceName);
				}
			}
			return list2;
		}

		internal void ProcessCriteriaCtx_EnlistedConnection(OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.PoolManager, OracleTraceFuncName.ProcessCriteriaCtx_EnlistedConnection);
			}
			try
			{
				if (string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName) && string.IsNullOrEmpty(connRefForCriteria.m_criteriaPdbName))
				{
					if (!string.IsNullOrEmpty(m_conStrServiceName))
					{
						connRefForCriteria.m_criteriaServiceName = m_conStrServiceName;
						return;
					}
					string serviceForDS = GetServiceForDS(m_cs.ServerID);
					if (!string.IsNullOrEmpty(serviceForDS))
					{
						connRefForCriteria.m_criteriaServiceName = serviceForDS;
					}
				}
				else if (string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName) && !string.IsNullOrEmpty(connRefForCriteria.m_criteriaPdbName) && (connRefForCriteria.m_criteriaPdbName.Equals("cdb$root", StringComparison.InvariantCultureIgnoreCase) || connRefForCriteria.m_criteriaPdbName.Equals("pdb$seed", StringComparison.InvariantCultureIgnoreCase)))
				{
					connRefForCriteria.m_criteriaServiceName = "SYS$USERS";
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.PoolManager, OracleTraceFuncName.ProcessCriteriaCtx_EnlistedConnection);
				}
			}
		}

		internal void ProcessCriteriaCtx_NonEnlistedConnection(ref OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.PoolManager, OracleTraceFuncName.ProcessCriteriaCtx_NonEnlistedConnection);
			}
			try
			{
				if (connRefForCriteria != null && string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName) && !string.IsNullOrEmpty(connRefForCriteria.m_criteriaPdbName) && (connRefForCriteria.m_criteriaPdbName.Equals("cdb$root", StringComparison.InvariantCultureIgnoreCase) || connRefForCriteria.m_criteriaPdbName.Equals("pdb$seed", StringComparison.InvariantCultureIgnoreCase)))
				{
					connRefForCriteria.m_criteriaServiceName = "SYS$USERS";
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Exit, OracleTraceClassName.PoolManager, OracleTraceFuncName.ProcessCriteriaCtx_NonEnlistedConnection);
				}
			}
		}

		internal virtual void ProcessCriteriaCtxAndAlterSessionIfReqd(OracleConnection connRefForCriteria, PR pr)
		{
			if (connRefForCriteria != null && pr.m_bCheckIfAlterSessionReqd)
			{
				bool[] array = pr.ProcessCriteriaCtx(connRefForCriteria);
				if (array != null && (array[0] || array[1]))
				{
					pr.AlterSession(array, connRefForCriteria);
				}
			}
		}

		internal PR GetNew(ConnectionString cs, OracleConnection connRefForCriteria, string instanceName = null, List<string> switchFailedInstNames = null)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetNew, Trace.GetCPInfo(null, null, instanceName, null));
			}
			PR val = null;
			try
			{
				if (m_semMaxPoolSize.WaitOne(0))
				{
					try
					{
						val = CreateNewPR(1, bForPoolPopulation: false, cs, connRefForCriteria, instanceName, switchFailedInstNames);
						return val;
					}
					finally
					{
						if (val == null)
						{
							m_currentMaxSemCount = m_semMaxPoolSize.Release();
						}
					}
				}
				return val;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetNew, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetNew, Trace.GetCPInfo(val as OracleConnectionImpl, null, instanceName, null));
				}
			}
		}

		public virtual bool RemoveCheckedInPR(PR pr, bool bForce)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR);
			}
			try
			{
				bool flag = false;
				if (bForce)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, "PM.RemoveCheckedInPR() : Get Idle Sempahore ");
					if (m_semIdleResource.WaitOne(10000))
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, "PM.RemoveCheckedInPR() : Received Idle Sempahore ");
						try
						{
							if (pr.m_cp.m_cpQueuePR.Remove(pr))
							{
								pr.m_pm.m_pmListPR.Remove(pr);
								if (pr.m_cp != null)
								{
									pr.m_cp.m_cpListPR.Remove(pr);
								}
								flag = true;
							}
						}
						finally
						{
							if (!flag)
							{
								m_currentIdleSemCount = m_semIdleResource.Release();
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, $"RemoveCheckedInPR() : Idle Sempahore count={m_currentIdleSemCount}");
							}
						}
					}
					else
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.Entry, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, "m_semIdleResource.WaitOne(10000) timed out");
						flag = false;
					}
				}
				else
				{
					flag = false;
					if (m_pmListPR.Remove(pr, m_cs.m_minPoolSize))
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, "PM.RemoveCheckedInPR() : Get Idle Sempahore ");
						if (m_semIdleResource.WaitOne(0))
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, "PM.RemoveCheckedInPR() : Received Idle Sempahore ");
							try
							{
								if (pr.m_cp == null || pr.m_cp.m_cpQueuePR.Remove(pr))
								{
									if (pr.m_cp != null)
									{
										pr.m_cp.m_cpListPR.Remove(pr);
									}
									flag = true;
								}
							}
							finally
							{
								if (!flag)
								{
									m_currentIdleSemCount = m_semIdleResource.Release();
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, $"RemoveCheckedInPR2() : Idle Sempahore count={m_currentIdleSemCount}");
									m_pmListPR.Add(pr);
								}
							}
						}
						else
						{
							m_pmListPR.Add(pr);
							flag = false;
						}
					}
					else
					{
						flag = false;
					}
				}
				return flag;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					string str = $"RemoveChekedInPR() : [({pr.m_endUserSessionId}:{pr.m_endUserSerialNum}) (CheckedOutByApp:{pr.m_bCheckedOutByApp}) (CheckedOutByDTC:{pr.m_bCheckedOutByDTC}) (PutCompleted:{pr.m_bPutCompleted})]";
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, " : " + str);
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedInPR, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
				}
			}
		}

		public virtual bool RemoveCheckedOutPR(PR pr, bool bForce)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedOutPR, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			try
			{
				bool flag = false;
				if ((!bForce) ? m_pmListPR.Remove(pr, m_cs.m_minPoolSize) : m_pmListPR.Remove(pr))
				{
					if (pr.m_cp != null)
					{
						pr.m_cp.m_cpListPR.Remove(pr);
					}
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedOutPR, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveCheckedOutPR, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
				}
			}
		}

		internal virtual bool Close(PR pr, OracleConnection connRefForCriteria, bool isConnectionCheckedout = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Close, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			bool flag = false;
			try
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					string text = string.Format("({5}:{6}) if ((!pr.m_bCheckedOutByApp({0}) && !pr.m_bCheckedOutByDTC({1})) || pr.m_deletionRequestor({2}) == DeletionRequestor.HA ||  string.Empty == pr.ServiceName({3})) (putcompleted={4})", pr.m_bCheckedOutByApp, pr.m_bCheckedOutByDTC, pr.m_deletionRequestor, pr.ServiceName, pr.m_bPutCompleted, pr.m_endUserSessionId, pr.m_endUserSerialNum);
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Close, text);
				}
				if ((!pr.m_bCheckedOutByApp && !pr.m_bCheckedOutByDTC) || pr.m_deletionRequestor == DeletionRequestor.HA || string.Empty == pr.ServiceName)
				{
					lock (pr)
					{
						if ((!pr.m_bCheckedOutByApp && !pr.m_bCheckedOutByDTC) || pr.m_deletionRequestor == DeletionRequestor.HA || string.Empty == pr.ServiceName)
						{
							lock (m_syncPRClose)
							{
								if (!pr.m_cs.m_pooling)
								{
									flag = RemoveCheckedOutPR(pr, bForce: true);
								}
								else if (pr.m_deletionRequestor == DeletionRequestor.ConnectionLifetime)
								{
									flag = RemoveCheckedOutPR(pr, bForce: true);
								}
								else if (pr.m_deletionRequestor == DeletionRequestor.Put)
								{
									flag = RemoveCheckedOutPR(pr, bForce: true);
								}
								else if (pr.m_deletionRequestor == DeletionRequestor.PoolRegulator && pr.m_bPutCompleted)
								{
									flag = RemoveCheckedInPR(pr, bForce: false);
								}
								else if (pr.m_deletionRequestor == DeletionRequestor.ClearPool && pr.m_bPutCompleted)
								{
									flag = RemoveCheckedInPR(pr, bForce: true);
								}
								else if (pr.m_deletionRequestor == DeletionRequestor.HA)
								{
									bool flag2 = false;
									bool flag3 = false;
									if (!isConnectionCheckedout)
									{
										flag = RemoveCheckedInPR(pr, bForce: true);
										flag3 = (flag2 = flag);
									}
									bool flag4 = false;
									if (pr != null)
									{
										flag4 = pr.IsTAFEnabled();
									}
									if (!flag4)
									{
										if (!flag)
										{
											flag = RemoveCheckedOutPR(pr, bForce: true);
											flag3 = true;
										}
									}
									else
									{
										Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Close, "PM.Close: TAF IS ENABLED");
										if (pr.m_failoverOccured)
										{
											string preFailoverInstName = pr.m_preFailoverInstName;
											pr.m_preFailoverInstName = null;
											pr.m_failoverOccured = false;
											Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Close, $"INSTANCE NAMES DO NOT MATCH{pr.m_instanceName}={preFailoverInstName}");
											pr.m_cp = m_dictDictCP[pr.ServiceName.ToLowerInvariant()][pr.m_instanceName.ToLowerInvariant()];
											flag = false;
											if (flag3 && flag2)
											{
												pr.m_cp.PutNewPR(pr, bForPoolPopulation: true);
											}
											else if (flag3)
											{
												pr.m_cp.PutNewPR(pr, bForPoolPopulation: false);
											}
										}
									}
									if (pr.m_cp == null)
									{
										Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Close, "pr.m_cp is NULL");
									}
								}
								if (flag)
								{
									pr.m_bPutCompleted = true;
								}
							}
						}
						if (flag)
						{
							if (pr.m_mtsTxnCtx != null)
							{
								try
								{
									(pr as OracleConnectionImpl).ResetMTSTxnCtx();
								}
								catch
								{
								}
							}
							pr.DisConnect(connRefForCriteria);
						}
					}
				}
				return flag;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.Close, ex);
				throw;
			}
			finally
			{
				if (flag && !pr.m_bClosedWithReplacement && m_cs.m_pooling)
				{
					m_currentMaxSemCount = m_semMaxPoolSize.Release();
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.Close, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null) + "(pmListPR.count={0})", m_pmListPR.Count.ToString());
				}
			}
		}

		public virtual void Put(PR pr, OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			try
			{
				bool flag = false;
				lock (pr)
				{
					pr.m_bPutCompleted = true;
					pr.EndRequest();
					if (pr.m_deletionRequestor != 0 || !pr.m_cs.m_pooling || string.Empty == pr.ServiceName)
					{
						pr.m_deletionRequestor = DeletionRequestor.Put;
						flag = pr.m_pm.Close(pr, connRefForCriteria);
					}
					else if (m_cs.m_connectionLifetime > 0 && DateTime.Now - pr.m_creationTime > m_cs.m_connectionLifetimeTimeSpan)
					{
						if (pr.m_deletionRequestor != DeletionRequestor.HA)
						{
							pr.m_deletionRequestor = DeletionRequestor.ConnectionLifetime;
						}
						flag = pr.m_pm.Close(pr, connRefForCriteria);
					}
				}
				if (flag)
				{
					pr = null;
				}
				if (pr == null)
				{
					return;
				}
				if (pr.IsTAFEnabled())
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Put, "PM.Put: TAF IS ENABLED");
					if (pr.m_failoverOccured)
					{
						string preFailoverInstName = pr.m_preFailoverInstName;
						pr.m_preFailoverInstName = null;
						pr.m_failoverOccured = false;
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Put, $"INSTANCE NAMES DO NOT MATCH{pr.m_instanceName}={preFailoverInstName}");
						if (m_dictDictCP[pr.ServiceName.ToLowerInvariant()] != null)
						{
							pr.m_cp = m_dictDictCP[pr.ServiceName.ToLowerInvariant()][pr.m_instanceName.ToLowerInvariant()];
						}
					}
				}
				if (pr.m_cp == null)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Put, "pr.m_cp is NULL");
				}
				bool flag2 = true;
				if (pr.m_cp != null)
				{
					if (pr.m_pm.m_cs.m_drcpEnabled == DrcpType.True && pr.bDRCPServerProcessAttached)
					{
						pr.DetachServerProcess(null, bUseDRCPMultiTag: false);
						pr.bDRCPServerProcessAttached = false;
						pr.bGotMatchingServerProcess = false;
					}
					pr.m_pm.m_criteriaMapper.GetId(pr as OracleConnectionImpl);
					string serviceName = pr.ServiceName;
					if (serviceName != null && serviceName != "null" && !serviceName.Equals(pr.m_cp.m_serviceName, StringComparison.InvariantCultureIgnoreCase))
					{
						CreateServiceCtx(pr);
						bool flag3 = true;
						flag2 = !flag3;
						bool migratePR = true;
						AddPRToPool(pr, flag3, migratePR);
					}
					else
					{
						pr.m_cp.Put(pr);
					}
				}
				if (flag2)
				{
					m_currentIdleSemCount = m_semIdleResource.Release();
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.Put, $"PM.Put() : Idle Sempahore count={m_currentIdleSemCount}");
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.Put, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.Put, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, "pm:put:reg2"));
				}
			}
		}

		public virtual void MarkAllPRsForDeletion(DateTime haEventUtcDateTime, bool isHAEvnt = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.MarkAllPRsForDeletion);
			}
			try
			{
				List<CP> list = m_pmListCP.GetList();
				for (int i = 0; i < list.Count; i++)
				{
					CP val = list[i];
					val.m_lastHADownEventUtcDateTime = haEventUtcDateTime;
					val.m_bInstanceDown = true;
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						string text = $"[pm_id={val.m_pm.m_id}][instance={val.m_instanceName}][instance_down={val.m_bInstanceDown}][type=ha_down_event][state_changed={true}][down_event_utc={haEventUtcDateTime.ToString()}][last_down_event_utc={val.m_lastHADownEventUtcDateTime.ToString()}]";
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.MarkAllPRsForDeletion, text);
					}
				}
				for (int j = 0; j < list.Count; j++)
				{
					list[j].MarkAllPRsForDeletion(haEventUtcDateTime, isHAEvnt);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.MarkAllPRsForDeletion, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.MarkAllPRsForDeletion);
				}
			}
		}

		public virtual void ClearAllPools(PR pr, bool isHAEvnt = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.ClearAllPools, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
			}
			try
			{
				m_fullDescriptor = null;
				m_bResolveTnsAlias = true;
				if (pr == null && OracleConnectionDispenser<PM, CP, PR>.m_listDataSources != null)
				{
					OracleConnectionDispenser<PM, CP, PR>.m_listDataSources.Remove(m_cs.m_dataSource);
				}
				List<CP> list = m_pmListCP.GetList();
				for (int i = 0; i < list.Count; i++)
				{
					list[i].ClearPool(pr, isHAEvnt);
				}
				lock (m_defaultEditionLocker)
				{
					m_defaultEditionDict.Clear();
				}
				if (m_shardRoutingCache != null)
				{
					m_shardRoutingCache.ClearCache();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.ClearAllPools, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.ClearAllPools, Trace.GetCPInfo(pr as OracleConnectionImpl, null, null, null));
				}
			}
		}

		internal PR GetEnlisted(ConnectionString csWithDiffOrNewPwd, bool bGetForApp, OracleConnection connRefForCriteria)
		{
			string text = null;
			Transaction transaction = null;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(null, null, null, null));
			}
			if (m_cs.m_enlist == Enlist.True && Transaction.Current != null)
			{
				transaction = Transaction.Current;
				text = transaction.TransactionInformation.LocalIdentifier;
			}
			PR val = null;
			string text2 = null;
			TransactionContext<PM, CP, PR> transactionContext = null;
			try
			{
				if (m_cs.m_drcpEnabled == DrcpType.True && !string.IsNullOrEmpty(m_cs.m_proxyUserId) && m_cs.m_securedPassword != null)
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(28150));
				}
				if (connRefForCriteria != null && m_cs.m_drcpEnabled == DrcpType.False && !string.IsNullOrEmpty(connRefForCriteria.m_criteriaConnCls))
				{
					throw new InvalidOperationException(OracleStringResourceManager.GetErrorMesg(-7601, "DRCPConnectionClass", "DRCP"));
				}
				ProcessCriteriaCtx_EnlistedConnection(connRefForCriteria);
				if (m_dictDictTxnCtx[text] == null)
				{
					lock (m_syncTxnCtx)
					{
						if (m_dictDictTxnCtx[text] == null)
						{
							m_dictDictTxnCtx[text] = new SyncDictionary<string, TransactionContext<PM, CP, PR>>();
						}
					}
				}
				if (!string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName) && (transactionContext = m_dictDictTxnCtx[text][connRefForCriteria.m_criteriaServiceName]) == null)
				{
					lock (m_syncTxnCtx)
					{
						if (!string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName) && (transactionContext = m_dictDictTxnCtx[text][connRefForCriteria.m_criteriaServiceName]) == null)
						{
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ", servicename= " + connRefForCriteria.m_criteriaServiceName + ") txnCtx not available (1)");
							}
							transactionContext = m_pmListTxnCtx.Dequeue();
							if (transactionContext == null)
							{
								transactionContext = new TransactionContext<PM, CP, PR>(this as PM, text);
							}
							else
							{
								transactionContext.ReInitialize(this as PM, transaction);
							}
							transactionContext.m_mtsTxnRM = transactionContext.GetRM(m_cs, connRefForCriteria.m_criteriaServiceName, connRefForCriteria.m_criteriaPdbName, transaction);
							transactionContext.m_affinityInstanceName = transactionContext.m_mtsTxnRM.m_txnAffInstanceName;
							transaction.TransactionCompleted += transactionContext.m_mtsTxnRM.MTSTransactionCompleted;
							transactionContext.m_mtsTxnRM.m_connStrs.AddIfNotExist(m_cs);
							m_dictDictTxnCtx[text][connRefForCriteria.m_criteriaServiceName] = transactionContext;
						}
					}
				}
				if (transactionContext == null || string.IsNullOrEmpty(transactionContext.m_mtsTxnRM.m_txnAffInstanceName))
				{
					lock (m_dictDictTxnCtx[text])
					{
						if (transactionContext == null || string.IsNullOrEmpty(transactionContext.m_mtsTxnRM.m_txnAffInstanceName))
						{
							try
							{
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ") First Connection to enlist.  No Txn Affinity yet");
								}
								val = Get(csWithDiffOrNewPwd, bGetForApp, connRefForCriteria, null, bForceMatch: true);
								if (string.IsNullOrEmpty(connRefForCriteria.m_criteriaServiceName))
								{
									connRefForCriteria.m_criteriaServiceName = val.ServiceName;
								}
								if ((transactionContext = m_dictDictTxnCtx[text][connRefForCriteria.m_criteriaServiceName]) == null)
								{
									lock (m_syncTxnCtx)
									{
										if ((transactionContext = m_dictDictTxnCtx[text][connRefForCriteria.m_criteriaServiceName]) == null)
										{
											if (ProviderConfig.m_bTraceLevelPrivate)
											{
												Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ", servicename= " + connRefForCriteria.m_criteriaServiceName + ") txnCtx not available (2)");
											}
											transactionContext = m_pmListTxnCtx.Dequeue();
											if (transactionContext == null)
											{
												transactionContext = new TransactionContext<PM, CP, PR>(this as PM, text);
											}
											else
											{
												transactionContext.ReInitialize(this as PM, transaction);
											}
											transactionContext.m_mtsTxnRM = transactionContext.GetRM(m_cs, connRefForCriteria.m_criteriaServiceName, connRefForCriteria.m_criteriaPdbName, transaction);
											transactionContext.m_affinityInstanceName = transactionContext.m_mtsTxnRM.m_txnAffInstanceName;
											transaction.TransactionCompleted += transactionContext.m_mtsTxnRM.MTSTransactionCompleted;
											transactionContext.m_mtsTxnRM.m_connStrs.AddIfNotExist(m_cs);
											m_dictDictTxnCtx[text][connRefForCriteria.m_criteriaServiceName] = transactionContext;
										}
									}
								}
								MTSRMManager.CCPEnlistTransaction(val as OracleConnectionImpl, transaction, connRefForCriteria);
								transactionContext.m_affinityInstanceName = (transactionContext.m_mtsTxnRM.m_txnAffInstanceName = val.m_instanceName);
								if (ProviderConfig.m_bTraceLevelPrivate)
								{
									Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(affinity) (txnid=" + text + ") (rmid=" + transactionContext.m_mtsTxnRM.GetHashCode() + ") (affinity=" + transactionContext.m_mtsTxnRM.m_txnAffInstanceName + ") (sessid=" + val.m_endUserSessionId + ":" + val.m_endUserSerialNum + ")");
								}
								return val;
							}
							catch (Exception ex)
							{
								try
								{
									OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, ex);
								}
								catch
								{
								}
								if (val != null)
								{
									try
									{
										OracleConnectionDispenser<PM, CP, PR>.PutFromApp(val, null);
									}
									catch
									{
									}
								}
								throw;
							}
						}
						transactionContext.m_affinityInstanceName = transactionContext.m_mtsTxnRM.m_txnAffInstanceName;
					}
				}
				else
				{
					transactionContext.m_affinityInstanceName = transactionContext.m_mtsTxnRM.m_txnAffInstanceName;
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ") affinity is set to = " + transactionContext.m_affinityInstanceName + " using MTSTxnRM " + transactionContext.m_mtsTxnRM.m_RMGuid.ToString());
				}
				text2 = transactionContext.m_affinityInstanceName;
				bool flag = false;
				string[] array = null;
				if (connRefForCriteria != null)
				{
					flag = connRefForCriteria.m_shardKey != null || connRefForCriteria.m_shardGroupKey != null;
				}
				if (!(connRefForCriteria != null && flag))
				{
					array = new string[1]
					{
						text2
					};
				}
				else
				{
					array = GetShardInstances(connRefForCriteria);
					if (array != null)
					{
						text2 = array[0];
					}
					else
					{
						array = new string[0];
					}
				}
				int num = 0;
				while (val == null && num < array.Length)
				{
					text2 = array[num];
					if (text2 != null)
					{
						val = transactionContext.GetEnlisted(csWithDiffOrNewPwd, bGetForApp, connRefForCriteria, text2);
					}
					num++;
				}
				if (val != null)
				{
					if (OraclePool.m_bPerfNumberOfFreeConnections)
					{
						OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfFreeConnections, val as OracleConnectionImpl, val.m_cp as OraclePool);
					}
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ") affinity is set to = " + transactionContext.m_affinityInstanceName + " using enlisted Conn ID " + val.m_endUserSessionId);
					}
					return val;
				}
				MTSTxnBranch txnBranch = null;
				try
				{
					txnBranch = transactionContext.m_mtsTxnRM.GetTxnBranch(m_cs, transactionContext.m_affinityInstanceName);
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, $"[GetTxnBranch] (1) (txnid={text}) (affinity={transactionContext.m_affinityInstanceName}) (rmid={transactionContext.m_mtsTxnRM.GetHashCode()}) (rmtxid={transactionContext.m_mtsTxnRM.m_txnLocalID}) (brid={txnBranch.GetHashCode()}) (brtxnid={txnBranch.m_txnLocalID})");
					}
					if (txnBranch != null)
					{
						val = Get(csWithDiffOrNewPwd, bGetForApp, connRefForCriteria, transactionContext.m_affinityInstanceName, bForceMatch: true);
						if (string.Compare(txnBranch.m_dbInstance, val.m_instanceName) != 0)
						{
							transactionContext.m_mtsTxnRM.ReleaseTxnBranch(txnBranch);
							txnBranch = transactionContext.m_mtsTxnRM.GetTxnBranch(m_cs, val.m_instanceName);
							if (txnBranch == null)
							{
								throw new OracleException(ResourceStringConstants.CON_MTS_ENLIST_FAIL, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_MTS_ENLIST_FAIL));
							}
						}
						MTSRMManager.CCPEnlistTransaction(val as OracleConnectionImpl, transaction, transactionContext.m_mtsTxnRM, txnBranch);
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ") affinity is set to = " + transactionContext.m_affinityInstanceName + " using regular Conn ID " + val.m_endUserSessionId);
						}
						return val;
					}
				}
				catch (Exception ex2)
				{
					try
					{
						OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, ex2);
					}
					catch
					{
					}
					if (val != null)
					{
						try
						{
							OracleConnectionDispenser<PM, CP, PR>.PutFromApp(val, null);
						}
						catch
						{
						}
					}
					if (transactionContext != null && transactionContext.m_mtsTxnRM != null && txnBranch != null)
					{
						try
						{
							transactionContext.m_mtsTxnRM.ReleaseTxnBranch(txnBranch);
						}
						catch
						{
						}
					}
					throw;
				}
				if (!flag)
				{
					try
					{
						val = transactionContext.GetEnlisted(csWithDiffOrNewPwd, bGetForApp, connRefForCriteria, null, bEnforceAffinity: false);
						if (val != null)
						{
							if (OraclePool.m_bPerfNumberOfFreeConnections)
							{
								OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfFreeConnections, val as OracleConnectionImpl, val.m_cp as OraclePool);
							}
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ") affinity is set to = " + transactionContext.m_affinityInstanceName + " using any enlisted Conn ID " + val.m_endUserSessionId + "affinity is set to = " + transactionContext.m_affinityInstanceName);
							}
							return val;
						}
					}
					catch (Exception ex3)
					{
						try
						{
							OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, ex3);
						}
						catch
						{
						}
						throw;
					}
				}
				TxnBranchesByDBInst freeBranches = transactionContext.m_mtsTxnRM.GetFreeBranches(m_cs);
				if (freeBranches == null || freeBranches.BranchCount == 0)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						string text3 = null;
						text3 = ((freeBranches != null) ? " freeTxnBrancvhes.BranchCount = 0" : " freeTxnBranches = null");
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4352, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(null, null, null, "UnableToEnlist1") + text3);
					}
					throw new OracleException(ResourceStringConstants.CON_MTS_ENLIST_FAIL, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_MTS_ENLIST_FAIL));
				}
				List<string> keys = freeBranches.GetKeys();
				if (flag)
				{
					try
					{
						val = Get(csWithDiffOrNewPwd, bGetForApp, connRefForCriteria, text2, bForceMatch: true);
						if (val != null)
						{
							for (int i = 0; i < keys.Count; i++)
							{
								if (keys[i].Equals(val.m_instanceName) && freeBranches.DequeueBranch(keys[i], out txnBranch))
								{
									MTSRMManager.CCPEnlistTransaction(val as OracleConnectionImpl, transaction, transactionContext.m_mtsTxnRM, txnBranch);
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ") affinity is set to = " + transactionContext.m_affinityInstanceName + " using Conn ID " + val.m_endUserSessionId + " with any free TxnBranch without txnAffinity = " + keys[i]);
									}
									return val;
								}
							}
							try
							{
								OracleConnectionDispenser<PM, CP, PR>.PutFromApp(val, null);
							}
							catch
							{
							}
						}
					}
					catch (Exception ex4)
					{
						try
						{
							OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, ex4);
						}
						catch
						{
						}
						if (val != null)
						{
							try
							{
								OracleConnectionDispenser<PM, CP, PR>.PutFromApp(val, null);
							}
							catch
							{
							}
						}
						if (txnBranch != null)
						{
							try
							{
								freeBranches.EnqueueBranch(text2, txnBranch);
							}
							catch
							{
							}
						}
						throw;
					}
				}
				else
				{
					for (int j = 0; j < keys.Count; j++)
					{
						text2 = keys[j];
						if (!freeBranches.DequeueBranch(text2, out txnBranch))
						{
							continue;
						}
						try
						{
							val = Get(csWithDiffOrNewPwd, bGetForApp, connRefForCriteria, text2, bForceMatch: true);
							if (val != null)
							{
								MTSRMManager.CCPEnlistTransaction(val as OracleConnectionImpl, transaction, transactionContext.m_mtsTxnRM, txnBranch);
							}
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, "(txnid=" + text + ") affinity is set to = " + transactionContext.m_affinityInstanceName + " using Conn ID " + val.m_endUserSessionId + " with any free TxnBranch without txnAffinity = " + keys[j]);
							}
							return val;
						}
						catch (Exception ex5)
						{
							try
							{
								OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, ex5);
							}
							catch
							{
							}
							if (val != null)
							{
								try
								{
									OracleConnectionDispenser<PM, CP, PR>.PutFromApp(val, null);
								}
								catch
								{
								}
							}
							if (txnBranch != null)
							{
								try
								{
									freeBranches.EnqueueBranch(text2, txnBranch);
								}
								catch
								{
								}
							}
							throw;
						}
					}
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4352, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(null, null, null, "UnableToEnlist2") + " no free branch or connect to enlist");
				}
				throw new OracleException(ResourceStringConstants.CON_MTS_ENLIST_FAIL, string.Empty, string.Empty, OracleStringResourceManager.GetErrorMesg(ResourceStringConstants.CON_MTS_ENLIST_FAIL));
			}
			catch (Exception ex6)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, ex6);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(val as OracleConnectionImpl, null, null, null));
				}
			}
		}

		internal PR GetEnlisted(Transaction txn, string affinityInstance, int branchNum, bool bMustMatch, out bool bMatchFound, string serviceName, string pdbName)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(null, txn, affinityInstance, null) + "PM.GetEnlisted(aff={0};br={1};must={2})", affinityInstance, branchNum.ToString(), bMustMatch.ToString().Substring(0, 1));
			}
			PR val = null;
			string localIdentifier = txn.TransactionInformation.LocalIdentifier;
			bMatchFound = false;
			TransactionContext<PM, CP, PR> transactionContext = null;
			try
			{
				if (m_dictDictTxnCtx[localIdentifier] != null)
				{
					transactionContext = m_dictDictTxnCtx[localIdentifier][serviceName];
				}
				if (transactionContext != null)
				{
					val = transactionContext.GetEnlisted(affinityInstance, branchNum, bMustMatch, out bMatchFound);
					if (val != null)
					{
						return val;
					}
				}
				else
				{
					lock (m_syncTxnCtx)
					{
						if (m_dictDictTxnCtx[localIdentifier] == null || m_dictDictTxnCtx[localIdentifier][serviceName] == null)
						{
							transactionContext = m_pmListTxnCtx.Dequeue();
							if (transactionContext == null)
							{
								transactionContext = new TransactionContext<PM, CP, PR>(this as PM, localIdentifier);
							}
							else
							{
								transactionContext.ReInitialize(this as PM, txn);
							}
							transactionContext.m_mtsTxnRM = transactionContext.GetRM(m_cs, serviceName, pdbName, txn);
							transactionContext.m_affinityInstanceName = transactionContext.m_mtsTxnRM.m_txnAffInstanceName;
							transactionContext.m_mtsTxnRM.m_connStrs.AddIfNotExist(m_cs);
							txn.TransactionCompleted += transactionContext.m_mtsTxnRM.MTSTransactionCompleted;
							if (m_dictDictTxnCtx[localIdentifier] == null)
							{
								m_dictDictTxnCtx[localIdentifier] = new SyncDictionary<string, TransactionContext<PM, CP, PR>>();
							}
							m_dictDictTxnCtx[localIdentifier][serviceName] = transactionContext;
						}
					}
				}
				if (bMustMatch)
				{
					return null;
				}
				OracleConnection oracleConnection = new OracleConnection();
				oracleConnection.m_serviceName = serviceName;
				oracleConnection.m_pdbName = pdbName;
				oracleConnection.m_fromMTS = true;
				val = Get(m_cs, bGetForApp: false, oracleConnection, affinityInstance);
				if (val != null)
				{
					val.m_resPoolRefCount++;
				}
				return val;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetEnlisted, Trace.GetCPInfo(val as OracleConnectionImpl, txn, affinityInstance, null) + "PM.GetEnlisted(aff={0};br={1};must={2}) return (matchfound={3})", affinityInstance, branchNum.ToString(), bMustMatch.ToString().Substring(0, 1), bMatchFound.ToString().Substring(0, 1));
				}
			}
		}

		internal void InitializePSPEConn(Transaction txn, PR pr)
		{
			TransactionContext<PM, CP, PR> transactionContext = null;
			if (m_dictDictTxnCtx != null && m_dictDictTxnCtx.ContainsKey(txn.TransactionInformation.LocalIdentifier))
			{
				transactionContext = m_dictDictTxnCtx[txn.TransactionInformation.LocalIdentifier][pr.ServiceName];
			}
			if (transactionContext == null)
			{
				return;
			}
			lock (pr)
			{
				lock (transactionContext)
				{
					transactionContext.m_enlistedPRList[0] = pr;
					transactionContext.m_instances.Add(pr.m_instanceName);
					pr.m_bTxnCtxPrimaryCon = true;
				}
			}
		}

		internal MTSTxnRM GetRM(Transaction txn, OracleConnection connRefForCriteria, PR pr)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetRM);
			}
			try
			{
				string localIdentifier = txn.TransactionInformation.LocalIdentifier;
				TransactionContext<PM, CP, PR> transactionContext = null;
				if (m_dictDictTxnCtx[localIdentifier] != null)
				{
					transactionContext = m_dictDictTxnCtx[localIdentifier][pr.ServiceName];
				}
				if (transactionContext == null)
				{
					lock (m_syncTxnCtx)
					{
						if (m_dictDictTxnCtx[localIdentifier] != null)
						{
							transactionContext = m_dictDictTxnCtx[localIdentifier][pr.ServiceName];
						}
						if (transactionContext == null)
						{
							transactionContext = m_pmListTxnCtx.Dequeue();
							if (transactionContext == null)
							{
								transactionContext = new TransactionContext<PM, CP, PR>(this as PM, localIdentifier);
							}
							else
							{
								transactionContext.ReInitialize(this as PM, txn);
							}
							transactionContext.m_mtsTxnRM = transactionContext.GetRM(m_cs, connRefForCriteria.m_criteriaServiceName, connRefForCriteria.m_criteriaPdbName, txn);
							transactionContext.m_mtsTxnRM.m_connStrs.AddIfNotExist(m_cs);
							txn.TransactionCompleted += transactionContext.m_mtsTxnRM.MTSTransactionCompleted;
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								Trace.Write(OracleTraceLevel.Private, OracleTraceTag.MTS, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetRM, "(affinity) (txnid=" + localIdentifier + ") (rmid=" + transactionContext.m_mtsTxnRM.GetHashCode() + ") (affinity=" + transactionContext.m_mtsTxnRM.m_txnAffInstanceName + ") (sessid=" + pr.m_endUserSessionId + ":" + pr.m_endUserSerialNum + ")");
							}
							if (m_dictDictTxnCtx[localIdentifier] == null)
							{
								m_dictDictTxnCtx[localIdentifier] = new SyncDictionary<string, TransactionContext<PM, CP, PR>>();
							}
							m_dictDictTxnCtx[localIdentifier][pr.ServiceName] = transactionContext;
						}
					}
				}
				return transactionContext.m_mtsTxnRM;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetRM, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.GetRM);
				}
			}
		}

		internal void RemoveRM(string serviceName, Transaction txn)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM);
			}
			try
			{
				TransactionContext<PM, CP, PR> transactionContext = null;
				string localIdentifier = txn.TransactionInformation.LocalIdentifier;
				if (localIdentifier != null)
				{
					try
					{
						if (m_dictDictTxnCtx[localIdentifier] != null)
						{
							lock (m_syncTxnCtx)
							{
								if (m_dictDictTxnCtx[localIdentifier] != null)
								{
									transactionContext = m_dictDictTxnCtx[localIdentifier][serviceName];
								}
							}
						}
						else if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, $"Local txn id not found: {txn.TransactionInformation.LocalIdentifier}, pmid:{m_id}, threadid:{Thread.CurrentThread.ManagedThreadId}");
						}
					}
					catch
					{
					}
					try
					{
						if (m_dictDictTxnCtx[localIdentifier] != null)
						{
							lock (m_syncTxnCtx)
							{
								if (m_dictDictTxnCtx[localIdentifier] != null)
								{
									m_dictDictTxnCtx[localIdentifier].Remove(serviceName);
									if (ProviderConfig.m_bTraceLevelPrivate)
									{
										Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, $"Removing the txn ctx. Local txn id: {localIdentifier}, pmid:{m_id}, service:{serviceName}, threadid:{Thread.CurrentThread.ManagedThreadId}");
									}
									if (m_dictDictTxnCtx[localIdentifier].Count == 0)
									{
										m_dictDictTxnCtx.Remove(localIdentifier);
										if (ProviderConfig.m_bTraceLevelPrivate)
										{
											Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, $"Removing the txn ctx cache. Local txn id: {localIdentifier}, pmid:{m_id}, threadid:{Thread.CurrentThread.ManagedThreadId}");
										}
									}
								}
							}
						}
						else if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, $"Local txn id not found: {localIdentifier}, pmid:{m_id}, threadid:{Thread.CurrentThread.ManagedThreadId}");
						}
					}
					catch (Exception ex)
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, ex.ToString());
						}
					}
				}
				if (transactionContext != null)
				{
					try
					{
						transactionContext.RemoveRM();
					}
					catch
					{
					}
					transactionContext.m_mtsTxnRM = null;
					transactionContext.m_localTxnId = null;
					m_pmListTxnCtx.Enqueue(transactionContext);
				}
			}
			catch (Exception ex2)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, ex2);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM);
				}
			}
		}

		private void RLBGravitateThreadFunc(object state)
		{
			int num = 0;
			bool flag = false;
			string text = null;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM);
			}
			try
			{
				object[] obj = state as object[];
				num = (int)obj[0];
				string text2 = (string)obj[1];
				text = (string)obj[2];
				if (text2 == null)
				{
					flag = true;
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, num + " connections to be unpopulated by the regulator thread");
					}
				}
				else if (num == 0 && ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, "called due to misses");
				}
				CP val = null;
				string text3 = null;
				float num2 = -1f;
				float num3 = 0f;
				List<string> list = null;
				if (text2 != null)
				{
					list.Add(text2);
				}
				else
				{
					list = m_dictSvcCtx.GetKeys();
				}
				foreach (string item in list)
				{
					if (m_dictSvcCtx[item] == null)
					{
						continue;
					}
					RLB rLB = RLBManager.Get((m_dictSvcCtx[item].m_databaseName + "|" + item).ToLowerInvariant());
					if (rLB == null || m_pmListPR.Count <= 0)
					{
						continue;
					}
					for (int i = 0; i < rLB.m_instances.Length; i++)
					{
						text3 = rLB.m_instances[i];
						text2 = rLB.m_service;
						if (text3 == null)
						{
							continue;
						}
						CP val2 = m_dictDictCP[text2.ToLowerInvariant()][text3.ToLowerInvariant()];
						if (val2 != null)
						{
							float num4 = val2.m_cpListPR.Count * 100 / m_pmListPR.Count;
							float num5 = rLB.m_rlbPercentages[i];
							num3 = num4 - num5;
							if (num3 > num2)
							{
								val = val2;
								num2 = num3;
							}
						}
					}
				}
				if (val != null && val.m_cpListPR.Count > 0 && num2 > 5f)
				{
					if (!flag)
					{
						int count = val.m_cpListPR.Count;
						num = (int)(0.15f * (float)count);
						if (num == 0)
						{
							num = Math.Min(5, count - 1);
						}
					}
					if (num < 1)
					{
						return;
					}
					if (!flag)
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, "RLBGravitateThreadFunc(instance=" + val.m_instanceName + "; close request=" + num + ");");
						}
						PoolPopulationOption state2 = new PoolPopulationOption(num, num + m_pmListPR.Count, null, ignoreIncrPoolSize: false, text);
						ThreadPool.QueueUserWorkItem(new WaitCallback(PopulatePoolThreadFunc), state2);
						return;
					}
					UnPopulatePoolArgs state3 = new UnPopulatePoolArgs(val.m_serviceName, val.m_instanceName, 1);
					PoolPopulationOption state4 = new PoolPopulationOption(1, 1 + m_pmListPR.Count, null, ignoreIncrPoolSize: false, text);
					int num6 = 0;
					int num7 = 0;
					try
					{
						for (int j = 0; j < num; j++)
						{
							if (UnPopulatePool(state3) <= 0)
							{
								break;
							}
							num6++;
							if (PopulatePool(state4) != 0)
							{
								num7++;
								continue;
							}
							break;
						}
					}
					finally
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, "(RLB) (GRAV) RLBGravitateThreadFunc(attempt to close=" + num + "; closed=" + num6 + "; opened=" + num7 + ")");
						}
					}
					return;
				}
				if (num > 0 && flag)
				{
					ThreadPool.QueueUserWorkItem(new WaitCallback(UnPopulatePoolThreadFunc), new UnPopulatePoolArgs(null, null, num));
				}
				else if (!flag && ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, "(RLB) RLBGravitate() : no gravitation; max distribution dif = " + num2);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM, ex);
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveRM);
				}
			}
		}

		internal void RemoveAndRedistribute(RLB rlb, CP cp, int indexToBeRemoved)
		{
			try
			{
				DateTime now = DateTime.Now;
				if (rlb.m_removedInstances.Contains(rlb.m_instances[indexToBeRemoved]))
				{
					return;
				}
				int[] array = (int[])rlb.m_percentages.Clone();
				int num = 0;
				for (int num2 = array.Length - 1; num2 >= 0; num2--)
				{
					if (array[num2] > 0)
					{
						num = array[num2];
						break;
					}
				}
				int num3 = 0;
				num3 = ((indexToBeRemoved <= 0) ? array[0] : (array[indexToBeRemoved] - array[indexToBeRemoved - 1]));
				int num4 = num - num3;
				if (num4 <= 0)
				{
					return;
				}
				int num5 = 0;
				int num6 = 0;
				for (int i = 0; i < array.Length; i++)
				{
					if (i == indexToBeRemoved)
					{
						num6 = array[i];
						if (i > 0)
						{
							array[i] = array[i - 1];
						}
						else
						{
							array[i] = 0;
						}
						continue;
					}
					num5 = ((i <= 0) ? array[i] : (array[i] - num6));
					num6 = array[i];
					array[i] = (int)((float)num5 / (float)num4 * 10000f);
					if (i > 0)
					{
						array[i] += array[i - 1];
					}
				}
				lock (rlb.m_syncObject)
				{
					if (!cp.HasValidConnections && !(now < rlb.m_lastUpdateTime))
					{
						rlb.m_lastUpdateTime = now;
						if (!rlb.m_removedInstances.Contains(rlb.m_instances[indexToBeRemoved]))
						{
							rlb.m_removedInstances.Add(rlb.m_instances[indexToBeRemoved]);
							rlb.m_percentages = array;
						}
					}
				}
			}
			catch
			{
			}
		}

		internal void RemoveDeadConnections(PR pr)
		{
			pr.m_bReconnectAtNullState = true;
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				string str = $"({pr.m_endUserSessionId}:{pr.m_endUserSerialNum})";
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.PoolManager, OracleTraceFuncName.RemoveDeadConnections, str + " : (HA) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
			}
			pr.m_deletionRequestor = DeletionRequestor.ClearPool;
			if (!m_cs.m_pooling)
			{
				return;
			}
			if (!pr.m_bCheckedOutByApp && !pr.m_bCheckedOutByDTC && pr.m_bPutCompleted && (pr.m_mtsTxnCtx == null || (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.None)))
			{
				lock (pr)
				{
					if (!pr.m_bCheckedOutByApp && !pr.m_bCheckedOutByDTC && pr.m_bPutCompleted && (pr.m_mtsTxnCtx == null || (pr.m_mtsTxnCtx != null && pr.m_mtsTxnCtx.m_txnType == MTSTxnType.None)))
					{
						pr.m_pm.Close(pr, null);
					}
				}
			}
			if (!Monitor.TryEnter(m_lockDeadConnectionScan))
			{
				return;
			}
			try
			{
				if (Monitor.TryEnter(m_lockUnPopulatePool))
				{
					try
					{
						UnPopulatePoolArgs state = new UnPopulatePoolArgs(null, null, -1);
						ThreadPool.QueueUserWorkItem(new WaitCallback(UnPopulatePoolThreadFunc), state);
					}
					finally
					{
						Monitor.Exit(m_lockUnPopulatePool);
					}
				}
			}
			finally
			{
				Monitor.Exit(m_lockDeadConnectionScan);
			}
		}
	}
}
